├── LICENSE ├── README.md ├── result_pg_11_tpcc.txt ├── tpcc-scm-1.rockspec ├── tpcc.lua ├── tpcc.lua.old ├── tpcc_check.lua ├── tpcc_common.lua ├── tpcc_common.lua.old ├── tpcc_run.lua └── tpcc_run.lua.old /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2018 Percona, LLC 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sysbench-tpcc 2 | 3 | TPCC-like workload for sysbench 1.0.x. 4 | **Make sure you are using sysbench 1.0.14 or better!** 5 | 6 | # modified by digoal 7 | 1\. Use prepared statement for postgresql. 8 | 9 | 2\. Use Read committed by default 10 | 11 | 3\. modified file: ```tpcc_common.lua, tpcc.lua, tpcc_run.lua``` 12 | 13 | # PostgreSQL example (use modified prepared statement by digoal) 14 | for exp. 15 | 16 | ``` 17 | unixsocket_dir='/tmp' 18 | port=1921 19 | user=postgres 20 | dbname=postgres 21 | ``` 22 | 23 | ## PostgreSQL: prepare data and tables 24 | ``` 25 | ./tpcc.lua --pgsql-host=/tmp --pgsql-port=1921 --pgsql-user=postgres --pgsql-db=postgres --threads=64 --tables=10 --scale=100 --trx_level=RC --db-ps-mode=auto --db-driver=pgsql prepare 26 | ``` 27 | 28 | or disable foreign key 29 | 30 | ``` 31 | ./tpcc.lua --pgsql-host=/tmp --pgsql-port=1921 --pgsql-user=postgres --pgsql-db=postgres --threads=64 --tables=10 --scale=100 --trx_level=RC --db-ps-mode=auto --db-driver=pgsql --use_fk=0 prepare 32 | ``` 33 | 34 | or use custom tablespace 35 | 36 | ``` 37 | export pgsql_table_options="tablespace tbs1" 38 | export pgsql_index_options="tablespace tbs2" 39 | 40 | ./tpcc.lua --pgsql-host=/tmp --pgsql-port=1921 --pgsql-user=postgres --pgsql-db=postgres --threads=64 --tables=10 --scale=100 --trx_level=RC --db-ps-mode=auto --db-driver=pgsql --use_fk=0 prepare 41 | ``` 42 | 43 | or use zheap custom storage_engine 44 | 45 | ``` 46 | export pgsql_table_options="with (storage_engine='zheap') tablespace tbs1" 47 | export pgsql_index_options="tablespace tbs2" 48 | 49 | ./tpcc.lua --pgsql-host=/tmp --pgsql-port=4001 --pgsql-user=postgres --pgsql-db=postgres --threads=64 --tables=20 --scale=100 --trx_level=RC --db-ps-mode=auto --db-driver=pgsql --use_fk=0 prepare 50 | ``` 51 | 52 | ## PostgreSQL: Run benchmark 53 | ``` 54 | ./tpcc.lua --pgsql-host=/tmp --pgsql-port=1921 --pgsql-user=postgres --pgsql-db=postgres --time=300 --threads=64 --report-interval=1 --tables=10 --scale=100 --trx_level=RC --db-ps-mode=auto --db-driver=pgsql --use_fk=0 --enable_purge=yes run 55 | ``` 56 | 57 | ## PostgreSQL: Cleanup 58 | ``` 59 | ./tpcc.lua --pgsql-host=/tmp --pgsql-port=1921 --pgsql-user=postgres --pgsql-db=postgres --time=300 --threads=64 --report-interval=1 --tables=10 --scale=100 --trx_level=RC --db-ps-mode=auto --db-driver=pgsql --use_fk=0 cleanup 60 | ``` 61 | 62 | # for MySQL 63 | # prepare data and tables 64 | 65 | ` 66 | ./tpcc.lua --mysql-socket=/tmp/mysql.sock --mysql-user=root --mysql-db=sbt --time=300 --threads=64 --report-interval=1 --tables=10 --scale=100 --db-driver=mysql prepare 67 | ` 68 | 69 | ## prepare for RocksDB 70 | 71 | ` 72 | ./tpcc.lua --mysql-socket=/tmp/mysql.sock --mysql-user=root --mysql-db=sbr --time=3000 --threads=64 --report-interval=1 --tables=10 --scale=100 --use_fk=0 --mysql_storage_engine=rocksdb --mysql_table_options='COLLATE latin1_bin' --trx_level=RC --db-driver=mysql prepare 73 | ` 74 | 75 | # Run benchmark 76 | 77 | ` 78 | ./tpcc.lua --mysql-socket=/tmp/mysql.sock --mysql-user=root --mysql-db=sbt --time=300 --threads=64 --report-interval=1 --tables=10 --scale=100 --db-driver=mysql run 79 | ` 80 | 81 | # Cleanup 82 | 83 | ` 84 | ./tpcc.lua --mysql-socket=/tmp/mysql.sock --mysql-user=root --mysql-db=sbt --time=300 --threads=64 --report-interval=1 --tables=10 --scale=100 --db-driver=mysql cleanup 85 | ` 86 | 87 | # options 88 | ``` 89 | -- Command line options 90 | sysbench.cmdline.options = { 91 | scale = 92 | {"Scale factor (warehouses)", 100}, 93 | tables = 94 | {"Number of tables", 1}, 95 | use_fk = 96 | {"Use foreign keys", 1}, 97 | force_pk = 98 | {"Force using auto-inc PK on history table", 0}, 99 | trx_level = 100 | {"Transaction isolation level (RC, RR or SER)", "RC"}, 101 | enable_purge = 102 | {"Use purge transaction (yes, no)", "no"}, 103 | report_csv = 104 | {"Report output in csv (yes, no)", "no"}, 105 | mysql_storage_engine = 106 | {"Storage engine, if MySQL is used", "innodb"}, 107 | mysql_table_options = 108 | {"Extra table options, if MySQL is used. e.g. 'COLLATE latin1_bin'", ""} 109 | } 110 | ``` 111 | 112 | -------------------------------------------------------------------------------- /result_pg_11_tpcc.txt: -------------------------------------------------------------------------------- 1 | # test env 2 | Aliyun ECS 3 | 4 | free -g 5 | total used free shared buff/cache available 6 | Mem: 503 3 240 65 259 432 7 | Swap: 0 0 0 8 | 9 | lscpu 10 | Architecture: x86_64 11 | CPU op-mode(s): 32-bit, 64-bit 12 | Byte Order: Little Endian 13 | CPU(s): 64 14 | On-line CPU(s) list: 0-63 15 | Thread(s) per core: 2 16 | Core(s) per socket: 32 17 | Socket(s): 1 18 | NUMA node(s): 1 19 | Vendor ID: GenuineIntel 20 | CPU family: 6 21 | Model: 85 22 | Model name: Intel(R) Xeon(R) Platinum 8163 CPU @ 2.50GHz 23 | Stepping: 4 24 | CPU MHz: 2500.008 25 | BogoMIPS: 5000.01 26 | Hypervisor vendor: KVM 27 | Virtualization type: full 28 | L1d cache: 32K 29 | L1i cache: 32K 30 | L2 cache: 1024K 31 | L3 cache: 33792K 32 | NUMA node0 CPU(s): 0-63 33 | Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 34 | 35 | df -h 36 | Filesystem Size Used Avail Use% Mounted on 37 | /dev/vda1 197G 4.2G 183G 3% / 38 | devtmpfs 252G 0 252G 0% /dev 39 | tmpfs 252G 8.5M 252G 1% /dev/shm 40 | tmpfs 252G 556K 252G 1% /run 41 | tmpfs 252G 0 252G 0% /sys/fs/cgroup 42 | /dev/mapper/vgdata01-lv03 4.0T 441G 3.6T 11% /data03 43 | /dev/mapper/vgdata01-lv02 4.0T 339G 3.7T 9% /data02 44 | /dev/mapper/vgdata01-lv01 4.0T 660G 3.4T 17% /data01 45 | tmpfs 51G 0 51G 0% /run/user/0 46 | 47 | # result 48 | ./tpcc.lua --pgsql-host=/tmp --pgsql-port=1921 --pgsql-user=postgres --pgsql-db=postgres --time=600 --threads=64 --report-interval=3 --tables=10 --scale=100 --trx_level=RC --db-driver=pgsql run 49 | sysbench 1.0.15 (using bundled LuaJIT 2.1.0-beta2) 50 | 51 | Running the test with following options: 52 | Number of threads: 64 53 | Report intermediate results every 3 second(s) 54 | Initializing random number generator from current time 55 | 56 | 57 | Initializing worker threads... 58 | 59 | Threads started! 60 | 61 | [ 3s ] thds: 64 tps: 12685.36 qps: 371763.65 (r/w/o: 164762.15/170932.67/36068.83) lat (ms,95%): 12.75 err/s 53.94 reconn/s: 0.00 62 | [ 6s ] thds: 64 tps: 15308.11 qps: 435366.55 (r/w/o: 198545.22/206205.11/30616.22) lat (ms,95%): 10.27 err/s 65.03 reconn/s: 0.00 63 | [ 9s ] thds: 64 tps: 15472.80 qps: 440416.11 (r/w/o: 200906.46/208564.37/30945.27) lat (ms,95%): 10.27 err/s 67.66 reconn/s: 0.00 64 | [ 12s ] thds: 64 tps: 15752.04 qps: 444756.08 (r/w/o: 202714.00/210537.68/31504.41) lat (ms,95%): 10.27 err/s 64.34 reconn/s: 0.00 65 | [ 15s ] thds: 64 tps: 15960.39 qps: 452761.93 (r/w/o: 206430.73/214410.76/31920.45) lat (ms,95%): 9.91 err/s 66.00 reconn/s: 0.00 66 | [ 18s ] thds: 64 tps: 15399.04 qps: 439089.37 (r/w/o: 200194.14/208096.83/30798.41) lat (ms,95%): 10.09 err/s 62.67 reconn/s: 0.00 67 | [ 21s ] thds: 64 tps: 16144.29 qps: 458680.78 (r/w/o: 209193.78/217198.76/32288.24) lat (ms,95%): 9.91 err/s 70.00 reconn/s: 0.00 68 | [ 24s ] thds: 64 tps: 16385.94 qps: 469205.27 (r/w/o: 214064.13/222368.93/32772.20) lat (ms,95%): 9.73 err/s 74.66 reconn/s: 0.00 69 | [ 27s ] thds: 64 tps: 15977.57 qps: 455018.46 (r/w/o: 207678.35/215385.31/31954.80) lat (ms,95%): 9.73 err/s 64.00 reconn/s: 0.00 70 | [ 30s ] thds: 64 tps: 16394.12 qps: 462351.06 (r/w/o: 210802.72/218759.76/32788.58) lat (ms,95%): 9.73 err/s 67.01 reconn/s: 0.00 71 | [ 33s ] thds: 64 tps: 16761.76 qps: 478247.29 (r/w/o: 218173.95/226550.16/33523.18) lat (ms,95%): 9.22 err/s 76.27 reconn/s: 0.00 72 | [ 36s ] thds: 64 tps: 15733.39 qps: 447029.24 (r/w/o: 203907.19/211654.95/31467.10) lat (ms,95%): 9.22 err/s 66.72 reconn/s: 0.00 73 | [ 39s ] thds: 64 tps: 16862.89 qps: 475272.32 (r/w/o: 216736.63/224810.92/33724.77) lat (ms,95%): 9.39 err/s 72.66 reconn/s: 0.00 74 | [ 42s ] thds: 64 tps: 16424.74 qps: 468518.57 (r/w/o: 213843.28/221825.81/32849.48) lat (ms,95%): 9.56 err/s 72.34 reconn/s: 0.00 75 | [ 45s ] thds: 64 tps: 16679.21 qps: 473711.48 (r/w/o: 216142.13/224209.92/33359.42) lat (ms,95%): 9.56 err/s 76.33 reconn/s: 0.00 76 | [ 48s ] thds: 64 tps: 16492.65 qps: 467785.55 (r/w/o: 213398.98/221401.28/32985.29) lat (ms,95%): 9.73 err/s 65.34 reconn/s: 0.00 77 | [ 51s ] thds: 64 tps: 15617.14 qps: 443160.43 (r/w/o: 202139.87/209786.95/31233.62) lat (ms,95%): 9.73 err/s 67.33 reconn/s: 0.00 78 | [ 54s ] thds: 64 tps: 16237.84 qps: 463967.24 (r/w/o: 211760.90/219730.99/32475.34) lat (ms,95%): 9.73 err/s 77.00 reconn/s: 0.00 79 | [ 57s ] thds: 64 tps: 16861.01 qps: 480092.45 (r/w/o: 218968.13/227401.30/33723.02) lat (ms,95%): 9.39 err/s 76.33 reconn/s: 0.00 80 | [ 60s ] thds: 64 tps: 16474.08 qps: 468649.83 (r/w/o: 213752.06/221949.94/32947.83) lat (ms,95%): 9.73 err/s 63.33 reconn/s: 0.00 81 | [ 63s ] thds: 64 tps: 16404.26 qps: 464777.90 (r/w/o: 211904.63/220064.43/32808.84) lat (ms,95%): 9.73 err/s 66.00 reconn/s: 0.00 82 | [ 66s ] thds: 64 tps: 16781.41 qps: 476743.72 (r/w/o: 217408.01/225773.55/33562.15) lat (ms,95%): 9.39 err/s 66.67 reconn/s: 0.00 83 | [ 69s ] thds: 64 tps: 16230.69 qps: 461251.50 (r/w/o: 210451.05/218338.40/32462.06) lat (ms,95%): 9.56 err/s 69.33 reconn/s: 0.00 84 | [ 72s ] thds: 64 tps: 16249.77 qps: 460457.17 (r/w/o: 209964.29/217993.67/32499.21) lat (ms,95%): 9.91 err/s 71.34 reconn/s: 0.00 85 | [ 75s ] thds: 64 tps: 15680.47 qps: 446166.40 (r/w/o: 203648.50/211157.29/31360.61) lat (ms,95%): 9.73 err/s 66.32 reconn/s: 0.00 86 | [ 78s ] thds: 64 tps: 16596.98 qps: 474419.12 (r/w/o: 216545.18/224679.65/33194.29) lat (ms,95%): 9.39 err/s 72.01 reconn/s: 0.00 87 | [ 81s ] thds: 64 tps: 16517.85 qps: 471434.95 (r/w/o: 215084.74/223314.50/33035.71) lat (ms,95%): 9.56 err/s 70.00 reconn/s: 0.00 88 | [ 84s ] thds: 64 tps: 16349.85 qps: 464468.50 (r/w/o: 211953.36/219815.44/32699.70) lat (ms,95%): 9.73 err/s 72.34 reconn/s: 0.00 89 | [ 87s ] thds: 64 tps: 16411.97 qps: 465186.45 (r/w/o: 212106.60/220255.92/32823.94) lat (ms,95%): 9.73 err/s 60.67 reconn/s: 0.00 90 | [ 90s ] thds: 64 tps: 16549.92 qps: 473098.75 (r/w/o: 215904.23/224094.69/33099.84) lat (ms,95%): 9.73 err/s 83.99 reconn/s: 0.00 91 | [ 93s ] thds: 64 tps: 15616.52 qps: 443803.98 (r/w/o: 202548.75/210021.52/31233.70) lat (ms,95%): 9.91 err/s 68.33 reconn/s: 0.00 92 | [ 96s ] thds: 64 tps: 16213.60 qps: 461744.21 (r/w/o: 210738.86/218578.82/32426.54) lat (ms,95%): 9.91 err/s 70.34 reconn/s: 0.00 93 | [ 99s ] thds: 64 tps: 16576.58 qps: 469367.65 (r/w/o: 214146.26/222067.89/33153.50) lat (ms,95%): 9.73 err/s 65.00 reconn/s: 0.00 94 | [ 102s ] thds: 64 tps: 16277.77 qps: 462477.20 (r/w/o: 210977.31/218944.36/32555.53) lat (ms,95%): 9.91 err/s 61.00 reconn/s: 0.00 95 | [ 105s ] thds: 64 tps: 16042.95 qps: 457617.65 (r/w/o: 208733.05/216799.36/32085.24) lat (ms,95%): 10.09 err/s 68.33 reconn/s: 0.00 96 | [ 108s ] thds: 64 tps: 15939.03 qps: 457439.73 (r/w/o: 208692.10/216868.91/31878.72) lat (ms,95%): 10.09 err/s 66.32 reconn/s: 0.00 97 | [ 111s ] thds: 64 tps: 16360.02 qps: 465873.98 (r/w/o: 212553.57/220600.37/32720.04) lat (ms,95%): 9.73 err/s 71.02 reconn/s: 0.00 98 | [ 114s ] thds: 64 tps: 16473.79 qps: 467096.48 (r/w/o: 213058.92/221090.32/32947.24) lat (ms,95%): 9.91 err/s 67.00 reconn/s: 0.00 99 | [ 117s ] thds: 64 tps: 16383.51 qps: 465041.45 (r/w/o: 212069.00/220205.09/32767.36) lat (ms,95%): 9.91 err/s 85.33 reconn/s: 0.00 100 | [ 120s ] thds: 64 tps: 16433.19 qps: 468602.32 (r/w/o: 213768.10/221968.19/32866.04) lat (ms,95%): 9.73 err/s 69.00 reconn/s: 0.00 101 | [ 123s ] thds: 64 tps: 16040.45 qps: 458075.32 (r/w/o: 208970.51/217023.91/32080.90) lat (ms,95%): 10.09 err/s 76.67 reconn/s: 0.00 102 | [ 126s ] thds: 64 tps: 16700.62 qps: 475440.07 (r/w/o: 216994.09/225044.40/33401.58) lat (ms,95%): 9.56 err/s 78.00 reconn/s: 0.00 103 | [ 129s ] thds: 64 tps: 16527.35 qps: 467064.56 (r/w/o: 212973.59/221036.61/33054.36) lat (ms,95%): 9.73 err/s 69.00 reconn/s: 0.00 104 | [ 132s ] thds: 64 tps: 16580.67 qps: 469907.70 (r/w/o: 214293.79/222452.57/33161.35) lat (ms,95%): 9.56 err/s 76.50 reconn/s: 0.00 105 | [ 135s ] thds: 64 tps: 16655.01 qps: 473220.50 (r/w/o: 215822.72/224087.43/33310.36) lat (ms,95%): 9.56 err/s 73.15 reconn/s: 0.00 106 | [ 138s ] thds: 64 tps: 16439.44 qps: 467519.79 (r/w/o: 213365.69/221275.55/32878.55) lat (ms,95%): 9.73 err/s 76.01 reconn/s: 0.00 107 | [ 141s ] thds: 64 tps: 16613.67 qps: 473130.41 (r/w/o: 215752.11/224150.61/33227.68) lat (ms,95%): 9.56 err/s 69.33 reconn/s: 0.00 108 | [ 144s ] thds: 64 tps: 16475.56 qps: 469145.65 (r/w/o: 214001.29/222193.24/32951.12) lat (ms,95%): 9.73 err/s 74.00 reconn/s: 0.00 109 | [ 147s ] thds: 64 tps: 16708.69 qps: 477001.94 (r/w/o: 217565.68/226019.20/33417.06) lat (ms,95%): 9.56 err/s 79.67 reconn/s: 0.00 110 | [ 150s ] thds: 64 tps: 16771.18 qps: 476995.57 (r/w/o: 217498.98/225954.24/33542.36) lat (ms,95%): 9.39 err/s 73.00 reconn/s: 0.00 111 | [ 153s ] thds: 64 tps: 17128.46 qps: 487748.25 (r/w/o: 222447.38/231043.61/34257.26) lat (ms,95%): 9.39 err/s 84.33 reconn/s: 0.00 112 | [ 156s ] thds: 64 tps: 17183.34 qps: 488150.56 (r/w/o: 222534.61/231249.59/34366.36) lat (ms,95%): 9.22 err/s 70.32 reconn/s: 0.00 113 | [ 159s ] thds: 64 tps: 17294.04 qps: 491226.89 (r/w/o: 224136.08/232503.06/34587.75) lat (ms,95%): 9.06 err/s 73.01 reconn/s: 0.00 114 | [ 162s ] thds: 64 tps: 17085.99 qps: 483986.11 (r/w/o: 220804.90/229008.90/34172.32) lat (ms,95%): 9.22 err/s 79.33 reconn/s: 0.00 115 | [ 165s ] thds: 64 tps: 16588.05 qps: 469852.45 (r/w/o: 214345.40/222330.93/33176.11) lat (ms,95%): 9.06 err/s 71.67 reconn/s: 0.00 116 | [ 168s ] thds: 64 tps: 16881.65 qps: 479911.39 (r/w/o: 218936.80/227210.95/33763.64) lat (ms,95%): 9.39 err/s 65.33 reconn/s: 0.00 117 | [ 171s ] thds: 64 tps: 16976.49 qps: 482543.39 (r/w/o: 220147.34/228443.08/33952.97) lat (ms,95%): 9.39 err/s 66.33 reconn/s: 0.00 118 | [ 174s ] thds: 64 tps: 16813.80 qps: 478021.19 (r/w/o: 218108.76/226285.16/33627.27) lat (ms,95%): 9.39 err/s 71.00 reconn/s: 0.00 119 | [ 177s ] thds: 64 tps: 16995.98 qps: 485841.70 (r/w/o: 221552.78/230296.61/33992.30) lat (ms,95%): 9.22 err/s 67.00 reconn/s: 0.00 120 | [ 180s ] thds: 64 tps: 17008.86 qps: 481399.84 (r/w/o: 219657.18/227724.94/34017.72) lat (ms,95%): 9.39 err/s 67.00 reconn/s: 0.00 121 | [ 183s ] thds: 64 tps: 16608.30 qps: 468036.04 (r/w/o: 213490.72/221329.39/33215.94) lat (ms,95%): 9.56 err/s 68.00 reconn/s: 0.00 122 | [ 186s ] thds: 64 tps: 16600.38 qps: 472656.86 (r/w/o: 215556.29/223899.48/33201.09) lat (ms,95%): 9.39 err/s 77.33 reconn/s: 0.00 123 | [ 189s ] thds: 64 tps: 17049.81 qps: 485303.34 (r/w/o: 221378.83/229824.56/34099.95) lat (ms,95%): 9.22 err/s 75.67 reconn/s: 0.00 124 | [ 192s ] thds: 64 tps: 17105.49 qps: 483795.39 (r/w/o: 220649.41/228935.33/34210.65) lat (ms,95%): 9.22 err/s 73.00 reconn/s: 0.00 125 | [ 195s ] thds: 64 tps: 16894.74 qps: 481737.66 (r/w/o: 219958.32/227989.53/33789.82) lat (ms,95%): 9.22 err/s 78.00 reconn/s: 0.00 126 | [ 198s ] thds: 64 tps: 16897.47 qps: 478789.12 (r/w/o: 218473.39/226520.79/33794.93) lat (ms,95%): 9.39 err/s 74.67 reconn/s: 0.00 127 | [ 201s ] thds: 64 tps: 16721.40 qps: 477133.37 (r/w/o: 217662.19/226028.72/33442.46) lat (ms,95%): 9.39 err/s 73.34 reconn/s: 0.00 128 | [ 204s ] thds: 64 tps: 16868.14 qps: 478510.44 (r/w/o: 218265.80/226508.70/33735.94) lat (ms,95%): 9.39 err/s 76.00 reconn/s: 0.00 129 | [ 207s ] thds: 64 tps: 16916.98 qps: 479656.51 (r/w/o: 218808.44/227013.77/33834.30) lat (ms,95%): 9.39 err/s 68.00 reconn/s: 0.00 130 | [ 210s ] thds: 64 tps: 16883.93 qps: 480488.21 (r/w/o: 219152.11/227567.91/33768.20) lat (ms,95%): 9.39 err/s 77.00 reconn/s: 0.00 131 | [ 213s ] thds: 64 tps: 17023.17 qps: 480935.97 (r/w/o: 219422.93/227466.70/34046.34) lat (ms,95%): 9.22 err/s 68.66 reconn/s: 0.00 132 | [ 216s ] thds: 64 tps: 17059.26 qps: 485355.76 (r/w/o: 221391.05/229846.85/34117.85) lat (ms,95%): 9.06 err/s 80.00 reconn/s: 0.00 133 | [ 219s ] thds: 64 tps: 17108.51 qps: 487948.98 (r/w/o: 222666.61/231064.69/34217.68) lat (ms,95%): 9.22 err/s 72.00 reconn/s: 0.00 134 | [ 222s ] thds: 64 tps: 16930.81 qps: 482541.89 (r/w/o: 220176.93/228504.00/33860.96) lat (ms,95%): 9.39 err/s 67.33 reconn/s: 0.00 135 | [ 225s ] thds: 64 tps: 16957.81 qps: 481596.81 (r/w/o: 219732.15/227948.38/33916.28) lat (ms,95%): 9.22 err/s 68.33 reconn/s: 0.00 136 | [ 228s ] thds: 64 tps: 17246.05 qps: 488487.58 (r/w/o: 222757.90/231237.59/34492.10) lat (ms,95%): 9.06 err/s 70.00 reconn/s: 0.00 137 | [ 231s ] thds: 64 tps: 17132.54 qps: 484342.74 (r/w/o: 221023.65/229054.34/34264.75) lat (ms,95%): 9.22 err/s 73.32 reconn/s: 0.00 138 | [ 234s ] thds: 64 tps: 17107.09 qps: 484879.11 (r/w/o: 221161.96/229503.64/34213.51) lat (ms,95%): 9.22 err/s 77.35 reconn/s: 0.00 139 | [ 237s ] thds: 64 tps: 17010.66 qps: 486065.15 (r/w/o: 221686.58/230356.58/34021.99) lat (ms,95%): 9.22 err/s 83.00 reconn/s: 0.00 140 | [ 240s ] thds: 64 tps: 16939.96 qps: 482108.85 (r/w/o: 219885.48/228343.46/33879.92) lat (ms,95%): 9.39 err/s 75.33 reconn/s: 0.00 141 | [ 243s ] thds: 64 tps: 16742.81 qps: 478657.18 (r/w/o: 218277.24/226893.98/33485.96) lat (ms,95%): 9.56 err/s 64.33 reconn/s: 0.00 142 | [ 246s ] thds: 64 tps: 16435.43 qps: 470599.11 (r/w/o: 214855.93/222872.32/32870.87) lat (ms,95%): 9.39 err/s 68.66 reconn/s: 0.00 143 | [ 249s ] thds: 64 tps: 17045.92 qps: 482287.02 (r/w/o: 220069.28/228125.89/34091.85) lat (ms,95%): 9.22 err/s 68.67 reconn/s: 0.00 144 | [ 252s ] thds: 64 tps: 17070.38 qps: 485935.93 (r/w/o: 221683.57/230111.93/34140.42) lat (ms,95%): 9.22 err/s 80.00 reconn/s: 0.00 145 | [ 255s ] thds: 64 tps: 16908.57 qps: 484649.81 (r/w/o: 221186.36/229645.98/33817.47) lat (ms,95%): 9.39 err/s 67.00 reconn/s: 0.00 146 | [ 258s ] thds: 64 tps: 17074.03 qps: 483034.58 (r/w/o: 220418.75/228468.10/34147.73) lat (ms,95%): 9.22 err/s 76.67 reconn/s: 0.00 147 | [ 261s ] thds: 64 tps: 16955.61 qps: 480106.27 (r/w/o: 218991.54/227203.18/33911.54) lat (ms,95%): 9.39 err/s 71.00 reconn/s: 0.00 148 | [ 264s ] thds: 64 tps: 16896.89 qps: 480915.13 (r/w/o: 219391.21/227730.82/33793.11) lat (ms,95%): 9.22 err/s 64.67 reconn/s: 0.00 149 | [ 267s ] thds: 64 tps: 17121.76 qps: 484935.45 (r/w/o: 221236.27/229455.65/34243.53) lat (ms,95%): 9.22 err/s 64.33 reconn/s: 0.00 150 | [ 270s ] thds: 64 tps: 16993.73 qps: 483434.69 (r/w/o: 220501.77/228944.80/33988.12) lat (ms,95%): 9.22 err/s 68.67 reconn/s: 0.00 151 | [ 273s ] thds: 64 tps: 17241.68 qps: 489334.34 (r/w/o: 223159.15/231692.16/34483.02) lat (ms,95%): 9.22 err/s 70.67 reconn/s: 0.00 152 | [ 276s ] thds: 64 tps: 17218.60 qps: 490397.31 (r/w/o: 223680.41/232279.37/34437.52) lat (ms,95%): 9.06 err/s 82.00 reconn/s: 0.00 153 | [ 279s ] thds: 64 tps: 17051.33 qps: 483003.75 (r/w/o: 220412.56/228488.54/34102.66) lat (ms,95%): 9.39 err/s 71.00 reconn/s: 0.00 154 | [ 282s ] thds: 64 tps: 17261.78 qps: 489124.09 (r/w/o: 223106.49/231494.38/34523.23) lat (ms,95%): 9.22 err/s 70.33 reconn/s: 0.00 155 | [ 285s ] thds: 64 tps: 17082.96 qps: 484509.74 (r/w/o: 221029.76/229315.07/34164.91) lat (ms,95%): 9.22 err/s 81.33 reconn/s: 0.00 156 | [ 288s ] thds: 64 tps: 16836.13 qps: 479662.36 (r/w/o: 218768.69/227220.08/33673.59) lat (ms,95%): 9.39 err/s 69.00 reconn/s: 0.00 157 | [ 291s ] thds: 64 tps: 16989.32 qps: 484789.51 (r/w/o: 221281.78/229529.10/33978.63) lat (ms,95%): 9.22 err/s 70.67 reconn/s: 0.00 158 | [ 294s ] thds: 64 tps: 17136.65 qps: 486752.44 (r/w/o: 222002.15/230476.98/34273.31) lat (ms,95%): 9.22 err/s 82.00 reconn/s: 0.00 159 | [ 297s ] thds: 64 tps: 17178.54 qps: 487178.69 (r/w/o: 222279.67/230542.28/34356.74) lat (ms,95%): 9.22 err/s 73.00 reconn/s: 0.00 160 | [ 300s ] thds: 64 tps: 16972.59 qps: 484985.30 (r/w/o: 221299.66/229740.13/33945.51) lat (ms,95%): 9.39 err/s 75.66 reconn/s: 0.00 161 | [ 303s ] thds: 64 tps: 17104.06 qps: 484859.01 (r/w/o: 221185.02/229465.88/34208.11) lat (ms,95%): 9.22 err/s 82.34 reconn/s: 0.00 162 | [ 306s ] thds: 64 tps: 16758.56 qps: 477539.74 (r/w/o: 217808.66/226213.95/33517.13) lat (ms,95%): 9.56 err/s 72.33 reconn/s: 0.00 163 | [ 309s ] thds: 64 tps: 16258.91 qps: 463757.36 (r/w/o: 211531.13/219708.42/32517.81) lat (ms,95%): 9.56 err/s 72.33 reconn/s: 0.00 164 | [ 312s ] thds: 64 tps: 16907.19 qps: 480938.11 (r/w/o: 219455.49/227668.58/33814.05) lat (ms,95%): 9.39 err/s 73.67 reconn/s: 0.00 165 | [ 315s ] thds: 64 tps: 16611.76 qps: 474246.95 (r/w/o: 216410.53/224612.57/33223.85) lat (ms,95%): 9.73 err/s 74.00 reconn/s: 0.00 166 | [ 318s ] thds: 64 tps: 16553.80 qps: 471770.68 (r/w/o: 215178.35/223484.74/33107.59) lat (ms,95%): 9.56 err/s 72.33 reconn/s: 0.00 167 | [ 321s ] thds: 64 tps: 16889.06 qps: 480302.06 (r/w/o: 219071.38/227453.57/33777.11) lat (ms,95%): 9.39 err/s 73.67 reconn/s: 0.00 168 | [ 324s ] thds: 64 tps: 16788.94 qps: 476175.30 (r/w/o: 217272.63/225325.11/33577.56) lat (ms,95%): 9.56 err/s 72.00 reconn/s: 0.00 169 | [ 327s ] thds: 64 tps: 16594.65 qps: 468864.25 (r/w/o: 213914.40/221759.22/33190.63) lat (ms,95%): 9.22 err/s 80.00 reconn/s: 0.00 170 | [ 330s ] thds: 64 tps: 16085.38 qps: 456032.52 (r/w/o: 208105.88/215755.90/32170.75) lat (ms,95%): 9.22 err/s 82.00 reconn/s: 0.00 171 | [ 333s ] thds: 64 tps: 17091.15 qps: 485507.53 (r/w/o: 221462.58/229862.65/34182.30) lat (ms,95%): 9.22 err/s 72.33 reconn/s: 0.00 172 | [ 336s ] thds: 64 tps: 16867.06 qps: 480268.18 (r/w/o: 219055.18/227479.88/33733.13) lat (ms,95%): 9.06 err/s 74.00 reconn/s: 0.00 173 | [ 339s ] thds: 64 tps: 17417.60 qps: 493103.17 (r/w/o: 224889.17/233378.47/34835.54) lat (ms,95%): 8.90 err/s 76.00 reconn/s: 0.00 174 | [ 342s ] thds: 64 tps: 17130.76 qps: 487127.76 (r/w/o: 222257.59/230607.97/34262.19) lat (ms,95%): 9.22 err/s 70.00 reconn/s: 0.00 175 | [ 345s ] thds: 64 tps: 17197.15 qps: 488296.03 (r/w/o: 222777.91/231124.16/34393.96) lat (ms,95%): 9.22 err/s 80.33 reconn/s: 0.00 176 | [ 348s ] thds: 64 tps: 16809.03 qps: 481698.62 (r/w/o: 219807.44/228273.45/33617.73) lat (ms,95%): 9.39 err/s 73.67 reconn/s: 0.00 177 | [ 351s ] thds: 64 tps: 17140.59 qps: 483906.29 (r/w/o: 220730.99/228893.79/34281.50) lat (ms,95%): 9.22 err/s 74.00 reconn/s: 0.00 178 | [ 354s ] thds: 64 tps: 17167.90 qps: 486047.61 (r/w/o: 221571.35/230140.13/34336.13) lat (ms,95%): 9.06 err/s 74.33 reconn/s: 0.00 179 | [ 357s ] thds: 64 tps: 17281.56 qps: 493767.79 (r/w/o: 225408.28/233796.72/34562.78) lat (ms,95%): 9.06 err/s 72.33 reconn/s: 0.00 180 | [ 360s ] thds: 64 tps: 16630.93 qps: 472919.62 (r/w/o: 215685.73/223971.70/33262.19) lat (ms,95%): 9.22 err/s 63.33 reconn/s: 0.00 181 | [ 363s ] thds: 64 tps: 17100.91 qps: 488269.14 (r/w/o: 222629.18/231438.13/34201.82) lat (ms,95%): 9.22 err/s 73.67 reconn/s: 0.00 182 | [ 366s ] thds: 64 tps: 17086.87 qps: 486060.01 (r/w/o: 221694.00/230193.27/34172.74) lat (ms,95%): 9.39 err/s 71.00 reconn/s: 0.00 183 | [ 369s ] thds: 64 tps: 16290.75 qps: 465298.48 (r/w/o: 212171.72/220544.59/32582.16) lat (ms,95%): 9.56 err/s 64.67 reconn/s: 0.00 184 | [ 372s ] thds: 64 tps: 16780.93 qps: 477020.14 (r/w/o: 217474.40/225983.54/33562.19) lat (ms,95%): 9.56 err/s 69.67 reconn/s: 0.00 185 | [ 375s ] thds: 64 tps: 16676.57 qps: 472461.46 (r/w/o: 215520.77/223587.56/33353.14) lat (ms,95%): 9.22 err/s 73.33 reconn/s: 0.00 186 | [ 378s ] thds: 64 tps: 16736.97 qps: 474330.02 (r/w/o: 216324.55/224531.52/33473.95) lat (ms,95%): 9.56 err/s 82.34 reconn/s: 0.00 187 | [ 381s ] thds: 64 tps: 16391.51 qps: 466778.48 (r/w/o: 212888.02/221107.44/32783.03) lat (ms,95%): 9.73 err/s 81.00 reconn/s: 0.00 188 | [ 384s ] thds: 64 tps: 16640.92 qps: 472157.64 (r/w/o: 215382.67/223493.47/33281.51) lat (ms,95%): 9.39 err/s 71.33 reconn/s: 0.00 189 | [ 387s ] thds: 64 tps: 16723.60 qps: 474601.42 (r/w/o: 216418.13/224736.43/33446.87) lat (ms,95%): 9.56 err/s 76.67 reconn/s: 0.00 190 | [ 390s ] thds: 64 tps: 16759.33 qps: 476885.50 (r/w/o: 217677.33/225689.51/33518.67) lat (ms,95%): 9.39 err/s 76.33 reconn/s: 0.00 191 | [ 393s ] thds: 64 tps: 16444.27 qps: 469313.23 (r/w/o: 214109.45/222314.92/32888.87) lat (ms,95%): 9.39 err/s 68.00 reconn/s: 0.00 192 | [ 396s ] thds: 64 tps: 16474.72 qps: 466475.46 (r/w/o: 212834.67/220691.36/32949.44) lat (ms,95%): 9.39 err/s 66.67 reconn/s: 0.00 193 | [ 399s ] thds: 64 tps: 16766.69 qps: 477942.64 (r/w/o: 217942.96/226465.97/33533.71) lat (ms,95%): 9.56 err/s 65.67 reconn/s: 0.00 194 | [ 402s ] thds: 64 tps: 16776.64 qps: 478033.50 (r/w/o: 218041.36/226438.85/33553.29) lat (ms,95%): 9.39 err/s 70.67 reconn/s: 0.00 195 | [ 405s ] thds: 64 tps: 17035.83 qps: 480716.48 (r/w/o: 219312.12/227333.37/34070.99) lat (ms,95%): 9.39 err/s 79.00 reconn/s: 0.00 196 | [ 408s ] thds: 64 tps: 16978.36 qps: 483357.82 (r/w/o: 220608.37/228792.39/33957.06) lat (ms,95%): 9.22 err/s 72.33 reconn/s: 0.00 197 | [ 411s ] thds: 64 tps: 16751.25 qps: 477581.14 (r/w/o: 217834.92/226243.72/33502.50) lat (ms,95%): 9.22 err/s 71.67 reconn/s: 0.00 198 | [ 414s ] thds: 64 tps: 16818.41 qps: 477492.28 (r/w/o: 217761.38/226093.75/33637.16) lat (ms,95%): 9.39 err/s 70.66 reconn/s: 0.00 199 | [ 417s ] thds: 64 tps: 16734.59 qps: 476639.00 (r/w/o: 217432.60/225738.23/33468.17) lat (ms,95%): 9.39 err/s 72.00 reconn/s: 0.00 200 | [ 420s ] thds: 64 tps: 16819.41 qps: 478411.72 (r/w/o: 218290.61/226481.97/33639.14) lat (ms,95%): 9.39 err/s 74.00 reconn/s: 0.00 201 | [ 423s ] thds: 64 tps: 16684.65 qps: 476768.16 (r/w/o: 217554.43/225844.43/33369.31) lat (ms,95%): 9.56 err/s 79.32 reconn/s: 0.00 202 | [ 426s ] thds: 64 tps: 16360.93 qps: 468054.61 (r/w/o: 213686.90/221645.84/32721.86) lat (ms,95%): 9.56 err/s 72.01 reconn/s: 0.00 203 | [ 429s ] thds: 64 tps: 16951.46 qps: 482720.23 (r/w/o: 220194.70/228622.60/33902.93) lat (ms,95%): 9.39 err/s 84.00 reconn/s: 0.00 204 | [ 432s ] thds: 64 tps: 16664.66 qps: 471740.93 (r/w/o: 215151.64/223259.64/33329.66) lat (ms,95%): 9.73 err/s 78.00 reconn/s: 0.00 205 | [ 435s ] thds: 64 tps: 16660.85 qps: 473381.45 (r/w/o: 215944.67/224114.76/33322.03) lat (ms,95%): 9.73 err/s 69.00 reconn/s: 0.00 206 | [ 438s ] thds: 64 tps: 16521.71 qps: 472935.78 (r/w/o: 215720.84/224171.85/33043.08) lat (ms,95%): 9.56 err/s 67.66 reconn/s: 0.00 207 | [ 441s ] thds: 64 tps: 16348.78 qps: 462400.11 (r/w/o: 210900.83/218801.38/32697.90) lat (ms,95%): 9.39 err/s 73.00 reconn/s: 0.00 208 | [ 444s ] thds: 64 tps: 16622.13 qps: 473560.92 (r/w/o: 216074.38/224242.28/33244.26) lat (ms,95%): 9.56 err/s 79.67 reconn/s: 0.00 209 | [ 447s ] thds: 64 tps: 16758.93 qps: 474915.23 (r/w/o: 216502.71/224895.00/33517.52) lat (ms,95%): 9.56 err/s 63.33 reconn/s: 0.00 210 | [ 450s ] thds: 64 tps: 16524.06 qps: 470065.41 (r/w/o: 214567.05/222449.91/33048.45) lat (ms,95%): 9.73 err/s 67.33 reconn/s: 0.00 211 | [ 453s ] thds: 64 tps: 16643.17 qps: 471929.82 (r/w/o: 215282.61/223360.86/33286.35) lat (ms,95%): 9.56 err/s 74.00 reconn/s: 0.00 212 | [ 456s ] thds: 64 tps: 16743.50 qps: 477052.66 (r/w/o: 217578.79/225987.21/33486.66) lat (ms,95%): 9.56 err/s 69.33 reconn/s: 0.00 213 | [ 459s ] thds: 64 tps: 16828.50 qps: 476405.50 (r/w/o: 217292.20/225456.29/33657.00) lat (ms,95%): 9.39 err/s 75.66 reconn/s: 0.00 214 | [ 462s ] thds: 64 tps: 16402.34 qps: 468310.80 (r/w/o: 213633.41/221872.38/32805.01) lat (ms,95%): 9.56 err/s 71.27 reconn/s: 0.00 215 | [ 465s ] thds: 64 tps: 16726.24 qps: 473350.85 (r/w/o: 215918.40/223980.98/33451.48) lat (ms,95%): 9.56 err/s 80.72 reconn/s: 0.00 216 | [ 468s ] thds: 64 tps: 16692.83 qps: 474738.47 (r/w/o: 216524.04/224828.44/33386.00) lat (ms,95%): 9.56 err/s 64.01 reconn/s: 0.00 217 | [ 471s ] thds: 64 tps: 16756.56 qps: 476568.41 (r/w/o: 217473.93/225580.70/33513.78) lat (ms,95%): 9.39 err/s 70.33 reconn/s: 0.00 218 | [ 474s ] thds: 64 tps: 16799.76 qps: 477347.85 (r/w/o: 217730.56/226018.11/33599.18) lat (ms,95%): 9.39 err/s 75.66 reconn/s: 0.00 219 | [ 477s ] thds: 64 tps: 16821.19 qps: 478079.76 (r/w/o: 218221.74/226215.32/33642.71) lat (ms,95%): 9.39 err/s 64.67 reconn/s: 0.00 220 | [ 480s ] thds: 64 tps: 16345.23 qps: 467552.83 (r/w/o: 213323.96/221540.08/32688.79) lat (ms,95%): 9.39 err/s 80.33 reconn/s: 0.00 221 | [ 483s ] thds: 64 tps: 16887.59 qps: 478812.25 (r/w/o: 218384.71/226650.35/33777.19) lat (ms,95%): 9.39 err/s 68.00 reconn/s: 0.00 222 | [ 486s ] thds: 64 tps: 16694.88 qps: 477973.22 (r/w/o: 218028.10/226555.71/33389.42) lat (ms,95%): 9.39 err/s 82.67 reconn/s: 0.00 223 | [ 489s ] thds: 64 tps: 16090.99 qps: 457109.33 (r/w/o: 208535.92/216391.75/32181.65) lat (ms,95%): 9.22 err/s 74.67 reconn/s: 0.00 224 | [ 492s ] thds: 64 tps: 16931.80 qps: 478768.98 (r/w/o: 218345.48/226559.56/33863.94) lat (ms,95%): 9.39 err/s 70.00 reconn/s: 0.00 225 | [ 495s ] thds: 64 tps: 17098.54 qps: 486299.95 (r/w/o: 221804.38/230298.82/34196.75) lat (ms,95%): 9.22 err/s 68.33 reconn/s: 0.00 226 | [ 498s ] thds: 64 tps: 16967.20 qps: 482723.47 (r/w/o: 220171.90/228617.50/33934.06) lat (ms,95%): 9.39 err/s 75.67 reconn/s: 0.00 227 | [ 501s ] thds: 64 tps: 16621.07 qps: 471180.57 (r/w/o: 214901.94/223035.82/33242.81) lat (ms,95%): 9.56 err/s 80.33 reconn/s: 0.00 228 | [ 504s ] thds: 64 tps: 16628.43 qps: 475307.05 (r/w/o: 216715.84/225335.35/33255.86) lat (ms,95%): 9.56 err/s 82.66 reconn/s: 0.00 229 | [ 507s ] thds: 64 tps: 17129.87 qps: 487538.08 (r/w/o: 222520.28/230757.07/34260.73) lat (ms,95%): 9.22 err/s 73.66 reconn/s: 0.00 230 | [ 510s ] thds: 64 tps: 16042.86 qps: 453897.98 (r/w/o: 207032.27/214778.99/32086.72) lat (ms,95%): 9.06 err/s 76.68 reconn/s: 0.00 231 | [ 513s ] thds: 64 tps: 17115.29 qps: 486388.05 (r/w/o: 221843.75/230314.39/34229.91) lat (ms,95%): 9.22 err/s 72.33 reconn/s: 0.00 232 | [ 516s ] thds: 64 tps: 16940.83 qps: 485430.22 (r/w/o: 221515.08/230033.49/33881.65) lat (ms,95%): 9.22 err/s 75.33 reconn/s: 0.00 233 | [ 519s ] thds: 64 tps: 16972.29 qps: 483775.38 (r/w/o: 220769.82/229060.63/33944.92) lat (ms,95%): 9.22 err/s 79.67 reconn/s: 0.00 234 | [ 522s ] thds: 64 tps: 17157.41 qps: 485485.36 (r/w/o: 221470.12/229700.75/34314.49) lat (ms,95%): 9.22 err/s 80.64 reconn/s: 0.00 235 | [ 525s ] thds: 64 tps: 17152.85 qps: 489269.06 (r/w/o: 223327.34/231635.68/34306.04) lat (ms,95%): 9.06 err/s 72.31 reconn/s: 0.00 236 | [ 528s ] thds: 64 tps: 17264.08 qps: 492752.71 (r/w/o: 224823.27/233402.28/34527.16) lat (ms,95%): 9.06 err/s 76.38 reconn/s: 0.00 237 | [ 531s ] thds: 64 tps: 17409.23 qps: 496030.37 (r/w/o: 226194.98/235016.93/34818.46) lat (ms,95%): 9.06 err/s 80.66 reconn/s: 0.00 238 | [ 534s ] thds: 64 tps: 17169.11 qps: 489491.85 (r/w/o: 223255.45/231897.18/34339.22) lat (ms,95%): 9.06 err/s 74.34 reconn/s: 0.00 239 | [ 537s ] thds: 64 tps: 17256.76 qps: 494113.52 (r/w/o: 225516.98/234084.03/34512.51) lat (ms,95%): 9.06 err/s 81.99 reconn/s: 0.00 240 | [ 540s ] thds: 64 tps: 16969.28 qps: 482495.26 (r/w/o: 220138.02/228418.33/33938.90) lat (ms,95%): 9.06 err/s 80.67 reconn/s: 0.00 241 | [ 543s ] thds: 64 tps: 17233.69 qps: 492404.68 (r/w/o: 224625.98/233310.99/34467.71) lat (ms,95%): 9.06 err/s 73.34 reconn/s: 0.00 242 | [ 546s ] thds: 64 tps: 17286.30 qps: 490862.58 (r/w/o: 223954.25/232335.39/34572.94) lat (ms,95%): 9.06 err/s 74.34 reconn/s: 0.00 243 | [ 549s ] thds: 64 tps: 17507.73 qps: 495822.24 (r/w/o: 226088.79/234718.99/35014.46) lat (ms,95%): 9.06 err/s 73.33 reconn/s: 0.00 244 | [ 552s ] thds: 64 tps: 17370.26 qps: 492712.68 (r/w/o: 224893.42/233078.40/34740.85) lat (ms,95%): 9.06 err/s 75.00 reconn/s: 0.00 245 | [ 555s ] thds: 64 tps: 17135.83 qps: 485810.15 (r/w/o: 221501.12/230037.04/34272.00) lat (ms,95%): 9.22 err/s 82.67 reconn/s: 0.00 246 | [ 558s ] thds: 64 tps: 17016.49 qps: 485013.37 (r/w/o: 221161.74/229817.98/34033.65) lat (ms,95%): 9.39 err/s 77.00 reconn/s: 0.00 247 | [ 561s ] thds: 64 tps: 17125.99 qps: 486007.80 (r/w/o: 221603.00/230153.49/34251.31) lat (ms,95%): 9.22 err/s 71.66 reconn/s: 0.00 248 | [ 564s ] thds: 64 tps: 17209.20 qps: 490650.47 (r/w/o: 223859.32/232372.41/34418.74) lat (ms,95%): 9.22 err/s 78.68 reconn/s: 0.00 249 | [ 567s ] thds: 64 tps: 17080.72 qps: 486607.94 (r/w/o: 222045.32/230401.52/34161.10) lat (ms,95%): 9.22 err/s 72.66 reconn/s: 0.00 250 | [ 570s ] thds: 64 tps: 17156.06 qps: 486398.05 (r/w/o: 221808.29/230277.31/34312.44) lat (ms,95%): 9.22 err/s 79.67 reconn/s: 0.00 251 | [ 573s ] thds: 64 tps: 17002.25 qps: 487431.20 (r/w/o: 222482.21/230945.17/34003.83) lat (ms,95%): 9.22 err/s 73.67 reconn/s: 0.00 252 | [ 576s ] thds: 64 tps: 17153.57 qps: 489076.46 (r/w/o: 223148.35/231620.31/34307.80) lat (ms,95%): 9.06 err/s 79.33 reconn/s: 0.00 253 | [ 579s ] thds: 64 tps: 16870.56 qps: 481605.98 (r/w/o: 219684.96/228179.91/33741.12) lat (ms,95%): 9.56 err/s 71.67 reconn/s: 0.00 254 | [ 582s ] thds: 64 tps: 17105.04 qps: 489485.50 (r/w/o: 223259.53/232016.55/34209.42) lat (ms,95%): 9.22 err/s 79.00 reconn/s: 0.00 255 | [ 585s ] thds: 64 tps: 16681.13 qps: 475035.24 (r/w/o: 216850.97/224822.02/33362.25) lat (ms,95%): 9.06 err/s 75.34 reconn/s: 0.00 256 | [ 588s ] thds: 64 tps: 17086.77 qps: 484715.93 (r/w/o: 221159.08/229382.97/34173.88) lat (ms,95%): 9.22 err/s 78.33 reconn/s: 0.00 257 | [ 591s ] thds: 64 tps: 17116.35 qps: 486033.83 (r/w/o: 221697.89/230103.23/34232.70) lat (ms,95%): 9.22 err/s 85.67 reconn/s: 0.00 258 | [ 594s ] thds: 64 tps: 16968.70 qps: 483163.37 (r/w/o: 220481.06/228744.58/33937.73) lat (ms,95%): 9.39 err/s 71.67 reconn/s: 0.00 259 | [ 597s ] thds: 64 tps: 16932.42 qps: 482617.22 (r/w/o: 220204.83/228548.21/33864.18) lat (ms,95%): 9.39 err/s 74.00 reconn/s: 0.00 260 | [ 600s ] thds: 64 tps: 16671.78 qps: 474341.31 (r/w/o: 216275.51/224722.23/33343.57) lat (ms,95%): 9.39 err/s 75.00 reconn/s: 0.00 261 | SQL statistics: 262 | queries performed: 263 | read: 130202475 264 | write: 135141530 265 | other: 20105862 266 | total: 285449867 267 | transactions: 10036898 (16722.66 per sec.) 268 | queries: 285449867 (475593.33 per sec.) 269 | ignored errors: 43740 (72.88 per sec.) 270 | reconnects: 0 (0.00 per sec.) 271 | 272 | General statistics: 273 | total time: 600.1949s 274 | total number of events: 10036898 275 | 276 | Latency (ms): 277 | min: 0.30 278 | avg: 3.82 279 | max: 1013.73 280 | 95th percentile: 9.39 281 | sum: 38372005.89 282 | 283 | Threads fairness: 284 | events (avg/stddev): 156826.5312/675.69 285 | execution time (avg/stddev): 599.5626/0.03 286 | -------------------------------------------------------------------------------- /tpcc-scm-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "tpcc" 2 | version = "scm-1" 3 | source = { 4 | url = "git+https://github.com/Percona-Lab/sysbench-tpcc/" 5 | } 6 | 7 | description = { 8 | summary = 9 | "TPCC-like workload for sysbench", 10 | detailed = [[ 11 | ## prepare data and tables 12 | 13 | ./tpcc.lua --mysql-socket=/tmp/mysql.sock --mysql-user=root --mysql-db=sbt --time=300 --threads=64 --report-interval=1 --tables=10 --scale=100 --db-driver=mysql prepare 14 | 15 | ## prepare for RocksDB 16 | 17 | ./tpcc.lua --mysql-socket=/tmp/mysql.sock --mysql-user=root --mysql-db=sbr --time=3000 --threads=64 --report-interval=1 --tables=10 --scale=100 --use_fk=0 --mysql_storage_engine=rocksdb --mysql_table_options='COLLATE latin1_bin' --trx_level=RC --db-driver=mysql prepare 18 | 19 | ## Run benchmark 20 | 21 | ./tpcc.lua --mysql-socket=/tmp/mysql.sock --mysql-user=root --mysql-db=sbt --time=300 --threads=64 --report-interval=1 --tables=10 --scale=100 --db-driver=mysql run 22 | 23 | ## Cleanup 24 | 25 | ./tpcc.lua --mysql-socket=/tmp/mysql.sock --mysql-user=root --mysql-db=sbt --time=300 --threads=64 --report-interval=1 --tables=10 --scale=100 --db-driver=mysql cleanup 26 | ]], 27 | homepage = "https://github.com/Percona-Lab/sysbench-tpcc/", 28 | license = "Apache-2.0" 29 | } 30 | 31 | dependencies = { 32 | "lua == 5.1" 33 | } 34 | 35 | build = { 36 | type = "builtin", 37 | modules = { 38 | tpcc = "tpcc.lua", 39 | tpcc_check = "tpcc_check.lua", 40 | tpcc_common = "tpcc_common.lua", 41 | tpcc_run = "tpcc_run.lua" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tpcc.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sysbench 2 | 3 | -- This program is free software; you can redistribute it and/or modify 4 | -- it under the terms of the GNU General Public License as published by 5 | -- the Free Software Foundation; either version 2 of the License, or 6 | -- (at your option) any later version. 7 | 8 | -- This program is distributed in the hope that it will be useful, 9 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | -- GNU General Public License for more details. 12 | 13 | -- You should have received a copy of the GNU General Public License 14 | -- along with this program; if not, write to the Free Software 15 | -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 16 | 17 | -- ---------------------------------------------------------------------- 18 | -- TPCC-like workload 19 | -- ---------------------------------------------------------------------- 20 | 21 | require("tpcc_common") 22 | require("tpcc_run") 23 | require("tpcc_check") 24 | 25 | function thread_init() 26 | 27 | drv = sysbench.sql.driver() 28 | con = drv:connect() 29 | 30 | set_isolation_level(drv,con) 31 | 32 | if drv:name() == "mysql" then 33 | con:query("SET autocommit=0") 34 | end 35 | 36 | 37 | -- prepare statement for postgresql 38 | 39 | if drv:name() == "pgsql" then 40 | for table_num = 1, sysbench.opt.tables 41 | do 42 | 43 | con:query(([[prepare p_new_order1_%d(int2,int2,int4) as SELECT c_discount, c_last, c_credit, w_tax 44 | FROM customer%d, warehouse%d 45 | WHERE w_id = $1 46 | AND c_w_id = w_id 47 | AND c_d_id = $2 48 | AND c_id = $3]]): 49 | format(table_num, table_num, table_num)) 50 | 51 | con:query(([[prepare p_new_order2_%d(int2,int2) as SELECT d_next_o_id, d_tax 52 | FROM district%d 53 | WHERE d_w_id = $1 54 | AND d_id = $2 FOR UPDATE]]): 55 | format(table_num, table_num)) 56 | 57 | 58 | con:query(([[prepare p_new_order3_%d(int4,int2,int2) as UPDATE district%d 59 | SET d_next_o_id = $1 60 | WHERE d_id = $2 AND d_w_id= $3]]):format(table_num, table_num)) 61 | 62 | con:query(([[prepare p_new_order4_%d(int4,int2,int2,int4,int2,int2) as INSERT INTO orders%d 63 | (o_id, o_d_id, o_w_id, o_c_id, o_entry_d, o_ol_cnt, o_all_local) 64 | VALUES ($1,$2,$3,$4,NOW(),$5,$6)]]): 65 | format(table_num, table_num)) 66 | 67 | con:query(([[prepare p_new_order5_%d(int4,int2,int2) as INSERT INTO new_orders%d (no_o_id, no_d_id, no_w_id) 68 | VALUES ($1,$2,$3)]]): 69 | format(table_num, table_num)) 70 | 71 | con:query(([[prepare p_new_order6_%d(int4) as SELECT i_price, i_name, i_data 72 | FROM item%d 73 | WHERE i_id = $1]]): 74 | format(table_num, table_num)) 75 | 76 | for d_id = 1, DIST_PER_WARE 77 | do 78 | con:query(([[prepare p_new_order7_%d_%s(int4,int2) as SELECT s_quantity, s_data, s_dist_%s s_dist 79 | FROM stock%d 80 | WHERE s_i_id = $1 AND s_w_id= $2 FOR UPDATE]]): 81 | format(table_num, string.format("%02d",d_id), string.format("%02d",d_id), table_num)) 82 | end 83 | 84 | con:query(([[prepare p_new_order8_%d(int2,int4,int2) as UPDATE stock%d 85 | SET s_quantity =$1 86 | WHERE s_i_id = $2 87 | AND s_w_id= $3]]): 88 | format(table_num, table_num)) 89 | 90 | 91 | con:query(([[prepare p_new_order9_%d(int4,int2,int2,int2,int4,int2,int2,float8,text) as INSERT INTO order_line%d 92 | (ol_o_id, ol_d_id, ol_w_id, ol_number, ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_dist_info) 93 | VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9)]]): 94 | format(table_num, table_num)) 95 | 96 | 97 | con:query(([[prepare p_payment1_%d(float8,int2) as UPDATE warehouse%d 98 | SET w_ytd = w_ytd + $1 99 | WHERE w_id = $2]]):format(table_num, table_num)) 100 | 101 | con:query(([[prepare p_payment2_%d(int2) as SELECT w_street_1, w_street_2, w_city, w_state, w_zip, w_name 102 | FROM warehouse%d 103 | WHERE w_id = $1]]):format(table_num, table_num)) 104 | 105 | con:query(([[prepare p_payment3_%d(float8,int2,int2) as UPDATE district%d 106 | SET d_ytd = d_ytd + $1 107 | WHERE d_w_id = $2 108 | AND d_id= $3]]):format(table_num, table_num)) 109 | 110 | con:query(([[prepare p_payment4_%d(int2,int2) as SELECT d_street_1, d_street_2, d_city, d_state, d_zip, d_name 111 | FROM district%d 112 | WHERE d_w_id = $1 113 | AND d_id = $2]]):format(table_num, table_num)) 114 | 115 | con:query(([[prepare p_payment5_%d(int2,int2,text) as SELECT count(c_id) namecnt 116 | FROM customer%d 117 | WHERE c_w_id = $1 118 | AND c_d_id=$2 119 | AND c_last=$3]]):format(table_num, table_num)) 120 | 121 | con:query(([[prepare p_payment6_%d(int2,int2,text) as SELECT c_id 122 | FROM customer%d 123 | WHERE c_w_id = $1 AND c_d_id= $2 124 | AND c_last=$3 ORDER BY c_first]]):format(table_num, table_num)) 125 | 126 | con:query(([[prepare p_payment7_%d(int2,int2,int4) as SELECT c_first, c_middle, c_last, c_street_1, 127 | c_street_2, c_city, c_state, c_zip, c_phone, 128 | c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_since 129 | FROM customer%d 130 | WHERE c_w_id = $1 131 | AND c_d_id= $2 132 | AND c_id=$3 FOR UPDATE]]) 133 | :format(table_num, table_num)) 134 | 135 | con:query(([[prepare p_payment8_%d(int2,int2,int4) as SELECT c_data 136 | FROM customer%d 137 | WHERE c_w_id = $1 138 | AND c_d_id = $2 139 | AND c_id= $3]]): 140 | format(table_num, table_num)) 141 | 142 | con:query(([[prepare p_payment9_%d(float8,float8,text,int2,int2,int4) as UPDATE customer%d 143 | SET c_balance=$1, c_ytd_payment=$2, c_data=$3 144 | WHERE c_w_id = $4 145 | AND c_d_id = $5 146 | AND c_id = $6]]) 147 | :format(table_num, table_num )) 148 | 149 | con:query(([[prepare p_payment10_%d(float8,float8,int2,int2,int4) as UPDATE customer%d 150 | SET c_balance=$1, c_ytd_payment=$2 151 | WHERE c_w_id = $3 152 | AND c_d_id = $4 153 | AND c_id = $5]]) 154 | :format(table_num, table_num )) 155 | 156 | con:query(([[prepare p_payment11_%d(int2,int2,int4,int2,int2,float8,text) as INSERT INTO history%d 157 | (h_c_d_id, h_c_w_id, h_c_id, h_d_id, h_w_id, h_date, h_amount, h_data) 158 | VALUES ($1,$2,$3,$4,$5,NOW(),$6,$7)]]) 159 | :format(table_num, table_num)) 160 | 161 | 162 | con:query(([[prepare p_orderstatus1_%d(int2,int2,text) as SELECT count(c_id) namecnt 163 | FROM customer%d 164 | WHERE c_w_id = $1 165 | AND c_d_id= $2 166 | AND c_last=$3]]): 167 | format(table_num, table_num)) 168 | 169 | 170 | con:query(([[prepare p_orderstatus2_%d(int2,int2,text) as SELECT c_balance, c_first, c_middle, c_id 171 | FROM customer%d 172 | WHERE c_w_id = $1 173 | AND c_d_id= $2 174 | AND c_last=$3 ORDER BY c_first]]): 175 | format(table_num, table_num)) 176 | 177 | con:query(([[prepare p_orderstatus3_%d(int2,int2,int4) as SELECT c_balance, c_first, c_middle, c_last 178 | FROM customer%d 179 | WHERE c_w_id = $1 180 | AND c_d_id= $2 181 | AND c_id=$3]]) 182 | :format(table_num, table_num )) 183 | 184 | con:query(([[prepare p_orderstatus4_%d(int2,int2,int4) as SELECT o_id, o_carrier_id, o_entry_d 185 | FROM orders%d 186 | WHERE o_w_id = $1 187 | AND o_d_id = $2 188 | AND o_c_id = $3 189 | ORDER BY o_id DESC]]): 190 | format(table_num, table_num )) 191 | 192 | con:query(([[prepare p_orderstatus5_%d(int2,int2,int4) as SELECT ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_delivery_d 193 | FROM order_line%d WHERE ol_w_id = $1 AND ol_d_id = $2 AND ol_o_id = $3]]) 194 | :format(table_num, table_num )) 195 | 196 | 197 | con:query(([[prepare p_delivery1_%d(int2,int2) as SELECT no_o_id 198 | FROM new_orders%d 199 | WHERE no_d_id = $1 200 | AND no_w_id = $2 201 | ORDER BY no_o_id ASC LIMIT 1 FOR UPDATE]]) 202 | :format(table_num, table_num)) 203 | 204 | con:query(([[prepare p_delivery2_%d(int4,int2,int2) as DELETE FROM new_orders%d 205 | WHERE no_o_id = $1 206 | AND no_d_id = $2 207 | AND no_w_id = $3]]) 208 | :format(table_num, table_num)) 209 | 210 | con:query(([[prepare p_delivery3_%d(int4,int2,int2) as SELECT o_c_id 211 | FROM orders%d 212 | WHERE o_id = $1 213 | AND o_d_id = $2 214 | AND o_w_id = $3]]) 215 | :format(table_num, table_num)) 216 | 217 | con:query(([[prepare p_delivery4_%d(int2,int4,int2,int2) as UPDATE orders%d 218 | SET o_carrier_id = $1 219 | WHERE o_id = $2 220 | AND o_d_id = $3 221 | AND o_w_id = $4]]) 222 | :format(table_num, table_num)) 223 | 224 | con:query(([[prepare p_delivery5_%d(int4,int2,int2) as UPDATE order_line%d 225 | SET ol_delivery_d = NOW() 226 | WHERE ol_o_id = $1 227 | AND ol_d_id = $2 228 | AND ol_w_id = $3]]) 229 | :format(table_num, table_num)) 230 | 231 | con:query(([[prepare p_delivery6_%d(int4,int2,int2) as SELECT SUM(ol_amount) sm 232 | FROM order_line%d 233 | WHERE ol_o_id = $1 234 | AND ol_d_id = $2 235 | AND ol_w_id = $3]]) 236 | :format(table_num, table_num)) 237 | 238 | 239 | con:query(([[prepare p_delivery7_%d(float8,int4,int2,int2) as UPDATE customer%d 240 | SET c_balance = c_balance + $1, 241 | c_delivery_cnt = c_delivery_cnt + 1 242 | WHERE c_id = $2 243 | AND c_d_id = $3 244 | AND c_w_id = $4]]) 245 | :format(table_num, table_num)) 246 | 247 | 248 | 249 | con:query(([[prepare p_stocklevel1_%d(int2,int2) as SELECT d_next_o_id 250 | FROM district%d 251 | WHERE d_id = $1 AND d_w_id= $2]]) 252 | :format( table_num, table_num )) 253 | 254 | 255 | con:query(([[prepare p_stocklevel2_%d(int2,int2,int4,int4,int2,int2) as SELECT COUNT(DISTINCT (s_i_id)) 256 | FROM order_line%d, stock%d 257 | WHERE ol_w_id = $1 258 | AND ol_d_id = $2 259 | AND ol_o_id < $3 260 | AND ol_o_id >= $4 261 | AND s_w_id= $5 262 | AND s_i_id=ol_i_id 263 | AND s_quantity < $6 ]]) 264 | :format(table_num, table_num, table_num )) 265 | 266 | con:query(([[prepare p_stocklevel3_%d(int2,int2,int4,int4) as SELECT DISTINCT ol_i_id FROM order_line%d 267 | WHERE ol_w_id = $1 AND ol_d_id = $2 268 | AND ol_o_id < $3 AND ol_o_id >= $4]]) 269 | :format(table_num, table_num )) 270 | 271 | con:query(([[prepare p_stocklevel4_%d(int2,int4,int2) as SELECT count(*) FROM stock%d 272 | WHERE s_w_id = $1 AND s_i_id = $2 273 | AND s_quantity < $3]]) 274 | :format(table_num, table_num) ) 275 | 276 | 277 | 278 | 279 | con:query(([[prepare p_purge1_%d(int2,int2) as SELECT min(no_o_id) mo 280 | FROM new_orders%d 281 | WHERE no_w_id = $1 AND no_d_id = $2]]) 282 | :format(table_num, table_num)) 283 | 284 | con:query(([[prepare p_purge2_%d(int2,int2,int4) as SELECT o_id FROM orders%d o, 285 | (SELECT o_c_id,o_w_id,o_d_id,count(distinct o_id) FROM orders%d WHERE o_w_id=$1 AND o_d_id=$2 AND o_id > 2100 286 | AND o_id < $3 GROUP BY o_c_id,o_d_id,o_w_id having count( distinct o_id) > 1 limit 1) t 287 | WHERE t.o_w_id=o.o_w_id and t.o_d_id=o.o_d_id and t.o_c_id=o.o_c_id limit 1 ]]) 288 | :format(table_num, table_num, table_num)) 289 | 290 | con:query(([[prepare p_purge3_%d(int2,int2,int4) as DELETE FROM order_line%d where ol_w_id=$1 AND ol_d_id=$2 AND ol_o_id=$3]]) 291 | :format(table_num, table_num)) 292 | 293 | con:query(([[prepare p_purge4_%d(int2,int2,int4) as DELETE FROM orders%d where o_w_id=$1 AND o_d_id=$2 and o_id=$3]]) 294 | :format(table_num, table_num)) 295 | 296 | con:query(([[prepare p_purge5_%d(int2,int2) as DELETE FROM history%d where ctid = any (array(select ctid from history%d where h_w_id=$1 AND h_d_id=$2 LIMIT 10))]]) 297 | :format(table_num, table_num, table_num )) 298 | 299 | end 300 | end 301 | end 302 | 303 | function event() 304 | -- print( NURand (1023,1,3000)) 305 | local max_trx = sysbench.opt.enable_purge == "yes" and 24 or 23 306 | local trx_type = sysbench.rand.uniform(1,max_trx) 307 | if trx_type <= 10 then 308 | trx="new_order" 309 | elseif trx_type <= 20 then 310 | trx="payment" 311 | elseif trx_type <= 21 then 312 | trx="orderstatus" 313 | elseif trx_type <= 22 then 314 | trx="delivery" 315 | elseif trx_type <= 23 then 316 | trx="stocklevel" 317 | elseif trx_type <= 24 then 318 | trx="purge" 319 | end 320 | 321 | -- Execute transaction 322 | _G[trx]() 323 | 324 | end 325 | 326 | function sysbench.hooks.before_restart_event(err) 327 | con:query("ROLLBACK") 328 | end 329 | 330 | function sysbench.hooks.report_intermediate(stat) 331 | -- -- print("my stat: ", val) 332 | if sysbench.opt.report_csv == "yes" then 333 | sysbench.report_csv(stat) 334 | else 335 | sysbench.report_default(stat) 336 | end 337 | end 338 | 339 | 340 | -- vim:ts=4 ss=4 sw=4 expandtab 341 | -------------------------------------------------------------------------------- /tpcc.lua.old: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sysbench 2 | 3 | -- This program is free software; you can redistribute it and/or modify 4 | -- it under the terms of the GNU General Public License as published by 5 | -- the Free Software Foundation; either version 2 of the License, or 6 | -- (at your option) any later version. 7 | 8 | -- This program is distributed in the hope that it will be useful, 9 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | -- GNU General Public License for more details. 12 | 13 | -- You should have received a copy of the GNU General Public License 14 | -- along with this program; if not, write to the Free Software 15 | -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 16 | 17 | -- ---------------------------------------------------------------------- 18 | -- TPCC-like workload 19 | -- ---------------------------------------------------------------------- 20 | 21 | require("tpcc_common") 22 | require("tpcc_run") 23 | require("tpcc_check") 24 | 25 | function thread_init() 26 | 27 | drv = sysbench.sql.driver() 28 | con = drv:connect() 29 | 30 | set_isolation_level(drv,con) 31 | 32 | if drv:name() == "mysql" then 33 | con:query("SET autocommit=0") 34 | end 35 | 36 | end 37 | 38 | function event() 39 | -- print( NURand (1023,1,3000)) 40 | local max_trx = sysbench.opt.enable_purge == "yes" and 24 or 23 41 | local trx_type = sysbench.rand.uniform(1,max_trx) 42 | if trx_type <= 10 then 43 | trx="new_order" 44 | elseif trx_type <= 20 then 45 | trx="payment" 46 | elseif trx_type <= 21 then 47 | trx="orderstatus" 48 | elseif trx_type <= 22 then 49 | trx="delivery" 50 | elseif trx_type <= 23 then 51 | trx="stocklevel" 52 | elseif trx_type <= 24 then 53 | trx="purge" 54 | end 55 | 56 | -- Execute transaction 57 | _G[trx]() 58 | 59 | end 60 | 61 | function sysbench.hooks.before_restart_event(err) 62 | con:query("ROLLBACK") 63 | end 64 | 65 | function sysbench.hooks.report_intermediate(stat) 66 | -- -- print("my stat: ", val) 67 | if sysbench.opt.report_csv == "yes" then 68 | sysbench.report_csv(stat) 69 | else 70 | sysbench.report_default(stat) 71 | end 72 | end 73 | 74 | 75 | -- vim:ts=4 ss=4 sw=4 expandtab 76 | -------------------------------------------------------------------------------- /tpcc_check.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (C) 2006-2017 Vadim Tkachenko, Percona 2 | 3 | -- This program is free software; you can redistribute it and/or modify 4 | -- it under the terms of the GNU General Public License as published by 5 | -- the Free Software Foundation; either version 2 of the License, or 6 | -- (at your option) any later version. 7 | 8 | -- This program is distributed in the hope that it will be useful, 9 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | -- GNU General Public License for more details. 12 | 13 | -- You should have received a copy of the GNU General Public License 14 | -- along with this program; if not, write to the Free Software 15 | -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 16 | 17 | -- ----------------------------------------------------------------------------- 18 | -- Check data code for TPCC benchmarks. 19 | -- ----------------------------------------------------------------------------- 20 | 21 | 22 | require("tpcc_common") 23 | 24 | 25 | function check_tables(drv, con, warehouse_num) 26 | 27 | straight_join_hint="," 28 | 29 | if drv:name() == "mysql" then 30 | straight_join_hint = "STRAIGHT_JOIN" 31 | end 32 | 33 | 34 | local pass1 = 1 35 | for table_num = 1, sysbench.opt.tables do 36 | -- print(string.format("Checking tables: %d for warehouse: %d\n", table_num, warehouse_num)) 37 | rs = con:query("SELECT d_w_id,sum(d_ytd)-max(w_ytd) diff FROM district"..table_num..",warehouse"..table_num.." WHERE d_w_id=w_id AND w_id="..warehouse_num.." group by d_w_id") 38 | 39 | for i = 1, rs.nrows do 40 | row = rs:fetch_row() 41 | local d_tax = tonumber(row[2]) 42 | if d_tax ~= 0 then 43 | pass1=0 44 | print(string.format("Check 1, warehouse: %d, table %d FAILED!!!", warehouse_num, table_num)) 45 | end 46 | end 47 | end 48 | 49 | if pass1 ~= 1 then 50 | print(string.format("Check 1, warehouse: %d FAILED!!!", warehouse_num)) 51 | else 52 | print(string.format("Check 1, warehouse: %d PASSED", warehouse_num)) 53 | end 54 | 55 | -- CHECK 2 56 | -- select dis.d_id, d_next_o_id-1,mo,mno from district1 dis, (select o_d_id,max(o_id) mo from orders1 where o_w_id=1 group by o_d_id) q, (select no_d_id,max(no_o_id) mno from new_orders1 where no_w_id=1 group by no_d_id) no where d_w_id=1 and q.o_d_id=dis.d_id and no.no_d_id=dis.d_id 57 | 58 | 59 | local pass2 = 1 60 | for table_num = 1, sysbench.opt.tables do 61 | -- print(string.format("Checking tables: %d for warehouse: %d\n", table_num, warehouse_num)) 62 | rs = con:query(string.format("SELECT dis.d_id, d_next_o_id-1,mo,mno FROM district%d dis, (SELECT o_d_id,max(o_id) mo FROM orders%d WHERE o_w_id=%d GROUP BY o_d_id) q, (select no_d_id,max(no_o_id) mno from new_orders%d where no_w_id=%d group by no_d_id) no where d_w_id=%d and q.o_d_id=dis.d_id and no.no_d_id=dis.d_id", table_num,table_num,warehouse_num, table_num, warehouse_num, warehouse_num)) 63 | 64 | for i = 1, rs.nrows do 65 | row = rs:fetch_row() 66 | local d1 = tonumber(row[2]) 67 | local d2 = tonumber(row[3]) 68 | local d3 = tonumber(row[4]) 69 | if d1 ~= d2 then 70 | pass2=0 71 | end 72 | if d1 ~= d3 then 73 | pass2=0 74 | end 75 | end 76 | end 77 | 78 | if pass2 == 1 then 79 | print(string.format("Check 2, warehouse: %d PASSED", warehouse_num)) 80 | else 81 | print(string.format("Check 2, warehouse: %d FAILED!!!", warehouse_num)) 82 | end 83 | 84 | local pass3 = 1 85 | for table_num = 1, sysbench.opt.tables do 86 | -- print(string.format("Checking tables: %d for warehouse: %d\n", table_num, warehouse_num)) 87 | rs = con:query(string.format("select no_d_id,max(no_o_id)-min(no_o_id)+1,count(*) from new_orders%d where no_w_id=%d group by no_d_id",table_num, warehouse_num)) 88 | 89 | for i = 1, rs.nrows do 90 | row = rs:fetch_row() 91 | local d1 = tonumber(row[2]) 92 | local d2 = tonumber(row[3]) 93 | if d1 ~= d2 then 94 | pass3=0 95 | end 96 | end 97 | end 98 | 99 | if pass3 == 1 then 100 | print(string.format("Check 3, warehouse: %d PASSED", warehouse_num)) 101 | else 102 | print(string.format("Check 3, warehouse: %d FAILED!!!", warehouse_num)) 103 | end 104 | 105 | local pass4 = 1 106 | for table_num = 1, sysbench.opt.tables do 107 | -- print(string.format("Checking tables: %d for warehouse: %d\n", table_num, warehouse_num)) 108 | rs = con:query(string.format([[SELECT count(*) 109 | FROM (SELECT o_d_id, SUM(o_ol_cnt) sm1, MAX(cn) as cn 110 | FROM orders%d,(SELECT ol_d_id, COUNT(*) cn 111 | FROM order_line%d 112 | WHERE ol_w_id=%d GROUP BY ol_d_id) ol 113 | WHERE o_w_id=%d AND ol_d_id=o_d_id GROUP BY o_d_id) t1 114 | WHERE sm1<>cn]],table_num, table_num, warehouse_num, warehouse_num)) 115 | 116 | for i = 1, rs.nrows do 117 | row = rs:fetch_row() 118 | local d1 = tonumber(row[1]) 119 | if d1 ~= 0 then 120 | pass4=0 121 | end 122 | end 123 | end 124 | 125 | if pass4 == 1 then 126 | print(string.format("Check 4, warehouse: %d PASSED", warehouse_num)) 127 | else 128 | print(string.format("Check 4, warehouse: %d FAILED!!!", warehouse_num)) 129 | end 130 | 131 | local pass5 = 1 132 | for table_num = 1, sysbench.opt.tables do 133 | -- print(string.format("Checking tables: %d for warehouse: %d\n", table_num, warehouse_num)) 134 | rs = con:query(string.format("SELECT count(*) FROM orders%d LEFT JOIN new_orders%d ON (no_w_id=o_w_id AND o_d_id=no_d_id AND o_id=no_o_id) where o_w_id=%d and ((o_carrier_id IS NULL and no_o_id IS NULL) OR (o_carrier_id IS NOT NULL and no_o_id IS NOT NULL )) ",table_num, table_num, warehouse_num)) 135 | 136 | for i = 1, rs.nrows do 137 | row = rs:fetch_row() 138 | local d1 = tonumber(row[1]) 139 | if d1 ~= 0 then 140 | pass5=0 141 | end 142 | end 143 | end 144 | 145 | if pass5 == 1 then 146 | print(string.format("Check 5, warehouse: %d PASSED", warehouse_num)) 147 | else 148 | print(string.format("Check 5, warehouse: %d FAILED!!!", warehouse_num)) 149 | end 150 | 151 | local pass7 = 1 152 | for table_num = 1, sysbench.opt.tables do 153 | -- print(string.format("Checking tables: %d for warehouse: %d\n", table_num, warehouse_num)) 154 | rs = con:query(string.format("SELECT count(*) FROM orders%d, order_line%d WHERE o_id=ol_o_id AND o_d_id=ol_d_id AND ol_w_id=o_w_id AND o_w_id=%d AND ((ol_delivery_d IS NULL and o_carrier_id IS NOT NULL) or (o_carrier_id IS NULL and ol_delivery_d IS NOT NULL ))",table_num, table_num, warehouse_num)) 155 | 156 | for i = 1, rs.nrows do 157 | row = rs:fetch_row() 158 | local d1 = tonumber(row[1]) 159 | if d1 ~= 0 then 160 | pass7=0 161 | end 162 | end 163 | end 164 | 165 | if pass7 == 1 then 166 | print(string.format("Check 7, warehouse: %d PASSED", warehouse_num)) 167 | else 168 | print(string.format("Check 7, warehouse: %d FAILED!!!", warehouse_num)) 169 | end 170 | 171 | local pass8 = 1 172 | for table_num = 1, sysbench.opt.tables do 173 | -- print(string.format("Checking tables: %d for warehouse: %d\n", table_num, warehouse_num)) 174 | rs = con:query(string.format("SELECT count(*) cn FROM (SELECT w_id,w_ytd,SUM(h_amount) sm FROM history%d,warehouse%d WHERE h_w_id=w_id and w_id=%d GROUP BY w_id) t1 WHERE w_ytd<>sm",table_num, table_num, warehouse_num)) 175 | 176 | for i = 1, rs.nrows do 177 | row = rs:fetch_row() 178 | local d1 = tonumber(row[1]) 179 | if d1 ~= 0 then 180 | pass8=0 181 | end 182 | end 183 | end 184 | 185 | if pass8 == 1 then 186 | print(string.format("Check 8, warehouse: %d PASSED", warehouse_num)) 187 | else 188 | print(string.format("Check 8, warehouse: %d FAILED!!!", warehouse_num)) 189 | end 190 | 191 | local pass9 = 1 192 | for table_num = 1, sysbench.opt.tables do 193 | -- print(string.format("Checking tables: %d for warehouse: %d\n", table_num, warehouse_num)) 194 | rs = con:query(string.format("SELECT COUNT(*) FROM (select d_id,d_w_id,sum(d_ytd) s1 from district%d group by d_id,d_w_id) d,(select h_d_id,h_w_id,sum(h_amount) s2 from history%d WHERE h_w_id=%d group by h_d_id, h_w_id) h WHERE h_d_id=d_id AND d_w_id=h_w_id and d_w_id=%d and s1<>s2",table_num, table_num, warehouse_num, warehouse_num)) 195 | 196 | for i = 1, rs.nrows do 197 | row = rs:fetch_row() 198 | local d1 = tonumber(row[1]) 199 | if d1 ~= 0 then 200 | pass9=0 201 | end 202 | end 203 | end 204 | 205 | if pass9 == 1 then 206 | print(string.format("Check 9, warehouse: %d PASSED", warehouse_num)) 207 | else 208 | print(string.format("Check 9, warehouse: %d FAILED!!!", warehouse_num)) 209 | end 210 | 211 | local pass10 = 1 212 | for table_num = 1, sysbench.opt.tables do 213 | -- print(string.format("Checking tables: %d for warehouse: %d\n", table_num, warehouse_num)) 214 | rs = con:query(string.format([[SELECT count(*) 215 | FROM ( SELECT c.c_id, c.c_d_id, c.c_w_id, c.c_balance c1, 216 | (SELECT sum(ol_amount) FROM orders%d ]] .. straight_join_hint .. [[ order_line%d 217 | WHERE OL_W_ID=O_W_ID 218 | AND OL_D_ID = O_D_ID 219 | AND OL_O_ID = O_ID 220 | AND OL_DELIVERY_D IS NOT NULL 221 | AND O_W_ID=c.c_w_id 222 | AND O_D_ID=c.C_D_ID 223 | AND O_C_ID=c.C_ID) sm, (SELECT sum(h_amount) from history%d 224 | WHERE H_C_W_ID=c.C_W_ID 225 | AND H_C_D_ID=c.C_D_ID 226 | AND H_C_ID=c.C_ID) smh 227 | FROM customer%d c 228 | WHERE c.c_w_id=%d ) t 229 | WHERE c1<>sm-smh]],table_num, table_num, table_num, table_num, warehouse_num)) 230 | 231 | for i = 1, rs.nrows do 232 | row = rs:fetch_row() 233 | local d1 = tonumber(row[1]) 234 | if d1 ~= 0 then 235 | pass10=0 236 | end 237 | end 238 | end 239 | 240 | if pass10 == 1 then 241 | print(string.format("Check 10, warehouse: %d PASSED", warehouse_num)) 242 | else 243 | print(string.format("Check 10, warehouse: %d FAILED!!!", warehouse_num)) 244 | end 245 | 246 | local pass12 = 1 247 | for table_num = 1, sysbench.opt.tables do 248 | -- print(string.format("Checking tables: %d for warehouse: %d\n", table_num, warehouse_num)) 249 | rs = con:query(string.format([[SELECT count(*) FROM (SELECT c.c_id, c.c_d_id, c.c_balance c1, c_ytd_payment, 250 | (SELECT sum(ol_amount) FROM orders%d ]] .. straight_join_hint .. [[ order_line%d 251 | WHERE OL_W_ID=O_W_ID AND OL_D_ID = O_D_ID AND OL_O_ID = O_ID AND OL_DELIVERY_D IS NOT NULL AND 252 | O_W_ID=c.c_w_id AND O_D_ID=c.C_D_ID AND O_C_ID=c.C_ID) sm FROM customer%d c WHERE c.c_w_id=%d) t1 253 | WHERE c1+c_ytd_payment <> sm ]] ,table_num, table_num, table_num, warehouse_num)) 254 | 255 | for i = 1, rs.nrows do 256 | row = rs:fetch_row() 257 | local d1 = tonumber(row[1]) 258 | if d1 ~= 0 then 259 | pass12=0 260 | end 261 | end 262 | end 263 | 264 | if pass12 == 1 then 265 | print(string.format("Check 12, warehouse: %d PASSED", warehouse_num)) 266 | else 267 | print(string.format("Check 12, warehouse: %d FAILED!!!", warehouse_num)) 268 | end 269 | end 270 | 271 | 272 | -- vim:ts=4 ss=4 sw=4 expandtab 273 | -------------------------------------------------------------------------------- /tpcc_common.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (C) 2006-2017 Vadim Tkachenko, Percona 2 | 3 | -- This program is free software; you can redistribute it and/or modify 4 | -- it under the terms of the GNU General Public License as published by 5 | -- the Free Software Foundation; either version 2 of the License, or 6 | -- (at your option) any later version. 7 | 8 | -- This program is distributed in the hope that it will be useful, 9 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | -- GNU General Public License for more details. 12 | 13 | -- You should have received a copy of the GNU General Public License 14 | -- along with this program; if not, write to the Free Software 15 | -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 16 | 17 | -- ----------------------------------------------------------------------------- 18 | -- Common code for TPCC benchmarks. 19 | -- ----------------------------------------------------------------------------- 20 | 21 | ffi = require("ffi") 22 | 23 | ffi.cdef[[ 24 | void sb_counter_inc(int, sb_counter_type); 25 | typedef uint32_t useconds_t; 26 | int usleep(useconds_t useconds); 27 | ]] 28 | 29 | 30 | function init() 31 | assert(event ~= nil, 32 | "this script is meant to be included by other TPCC scripts and " .. 33 | "should not be called directly.") 34 | end 35 | 36 | if sysbench.cmdline.command == nil then 37 | error("Command is required. Supported commands: prepare, run, cleanup, help") 38 | end 39 | 40 | MAXITEMS=100000 41 | DIST_PER_WARE=10 42 | CUST_PER_DIST=3000 43 | 44 | -- Command line options 45 | sysbench.cmdline.options = { 46 | scale = 47 | {"Scale factor (warehouses)", 100}, 48 | tables = 49 | {"Number of tables", 1}, 50 | use_fk = 51 | {"Use foreign keys", 1}, 52 | force_pk = 53 | {"Force using auto-inc PK on history table", 0}, 54 | trx_level = 55 | {"Transaction isolation level (RC, RR or SER)", "RC"}, 56 | enable_purge = 57 | {"Use purge transaction (yes, no)", "no"}, 58 | report_csv = 59 | {"Report output in csv (yes, no)", "no"}, 60 | mysql_storage_engine = 61 | {"Storage engine, if MySQL is used", "innodb"}, 62 | mysql_table_options = 63 | {"Extra table options, if MySQL is used. e.g. 'COLLATE latin1_bin'", ""} 64 | } 65 | 66 | function sleep(n) 67 | os.execute("sleep " .. tonumber(n)) 68 | end 69 | 70 | -- Create the tables and Prepare the dataset. This command supports parallel execution, i.e. will 71 | -- benefit from executing with --threads > 1 as long as --scale > 1 72 | function cmd_prepare() 73 | local drv = sysbench.sql.driver() 74 | local con = drv:connect() 75 | local show_query="SHOW TABLES" 76 | 77 | if drv:name() == "mysql" then 78 | con:query("SET FOREIGN_KEY_CHECKS=0") 79 | end 80 | 81 | -- create tables in parallel table per thread 82 | for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.tables, 83 | sysbench.opt.threads do 84 | create_tables(drv, con, i) 85 | end 86 | 87 | -- make sure all tables are created before we load data 88 | 89 | print("Waiting on tables 30 sec\n") 90 | sleep(30) 91 | 92 | for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.scale, 93 | sysbench.opt.threads do 94 | load_tables(drv, con, i) 95 | end 96 | 97 | end 98 | 99 | -- Check consistency 100 | -- benefit from executing with --threads > 1 as long as --scale > 1 101 | function cmd_check() 102 | local drv = sysbench.sql.driver() 103 | local con = drv:connect() 104 | 105 | for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.scale, 106 | sysbench.opt.threads do 107 | check_tables(drv, con, i) 108 | end 109 | 110 | end 111 | 112 | -- Implement parallel prepare and prewarm commands 113 | sysbench.cmdline.commands = { 114 | prepare = {cmd_prepare, sysbench.cmdline.PARALLEL_COMMAND}, 115 | check = {cmd_check, sysbench.cmdline.PARALLEL_COMMAND} 116 | } 117 | 118 | 119 | function create_tables(drv, con, table_num) 120 | local id_index_def, id_def 121 | local engine_def = "" 122 | -- local extra_table_options = "" 123 | -- local extra_index_options = "" 124 | local extra_table_options = os.getenv("pgsql_table_options") or "" 125 | local extra_index_options = os.getenv("pgsql_index_options") or "" 126 | local query 127 | local tinyint_type="smallint" 128 | local datetime_type="timestamp" 129 | 130 | if drv:name() == "mysql" or drv:name() == "attachsql" or 131 | drv:name() == "drizzle" 132 | then 133 | engine_def = "/*! ENGINE = " .. sysbench.opt.mysql_storage_engine .. " */" 134 | extra_table_options = sysbench.opt.mysql_table_options or "" 135 | tinyint_type="tinyint" 136 | datetime_type="datetime" 137 | end 138 | 139 | print(string.format("Creating tables: %d\n", table_num)) 140 | 141 | 142 | if drv:name() == "pgsql" 143 | then 144 | query = string.format([[ 145 | CREATE TABLE IF NOT EXISTS warehouse%d ( 146 | w_id smallint not null, 147 | w_name varchar(10), 148 | w_street_1 varchar(20), 149 | w_street_2 varchar(20), 150 | w_city varchar(20), 151 | w_state char(2), 152 | w_zip char(9), 153 | w_tax float8, 154 | w_ytd float8, 155 | primary key (w_id) 156 | ) %s %s]], 157 | table_num, engine_def, extra_table_options) 158 | else 159 | query = string.format([[ 160 | CREATE TABLE IF NOT EXISTS warehouse%d ( 161 | w_id smallint not null, 162 | w_name varchar(10), 163 | w_street_1 varchar(20), 164 | w_street_2 varchar(20), 165 | w_city varchar(20), 166 | w_state char(2), 167 | w_zip char(9), 168 | w_tax decimal(4,2), 169 | w_ytd decimal(12,2), 170 | primary key (w_id) 171 | ) %s %s]], 172 | table_num, engine_def, extra_table_options) 173 | end 174 | 175 | con:query(query) 176 | 177 | if drv:name() == "pgsql" 178 | then 179 | query = string.format([[ 180 | create table IF NOT EXISTS district%d ( 181 | d_id ]] .. tinyint_type .. [[ not null, 182 | d_w_id smallint not null, 183 | d_name varchar(10), 184 | d_street_1 varchar(20), 185 | d_street_2 varchar(20), 186 | d_city varchar(20), 187 | d_state char(2), 188 | d_zip char(9), 189 | d_tax float8, 190 | d_ytd float8, 191 | d_next_o_id int, 192 | primary key (d_w_id, d_id) 193 | ) %s %s]], 194 | table_num, engine_def, extra_table_options) 195 | else 196 | query = string.format([[ 197 | create table IF NOT EXISTS district%d ( 198 | d_id ]] .. tinyint_type .. [[ not null, 199 | d_w_id smallint not null, 200 | d_name varchar(10), 201 | d_street_1 varchar(20), 202 | d_street_2 varchar(20), 203 | d_city varchar(20), 204 | d_state char(2), 205 | d_zip char(9), 206 | d_tax decimal(4,2), 207 | d_ytd decimal(12,2), 208 | d_next_o_id int, 209 | primary key (d_w_id, d_id) 210 | ) %s %s]], 211 | table_num, engine_def, extra_table_options) 212 | end 213 | 214 | con:query(query) 215 | 216 | -- CUSTOMER TABLE 217 | 218 | if drv:name() == "pgsql" 219 | then 220 | query = string.format([[ 221 | create table IF NOT EXISTS customer%d ( 222 | c_id int not null, 223 | c_d_id ]] .. tinyint_type .. [[ not null, 224 | c_w_id smallint not null, 225 | c_first varchar(16), 226 | c_middle char(2), 227 | c_last varchar(16), 228 | c_street_1 varchar(20), 229 | c_street_2 varchar(20), 230 | c_city varchar(20), 231 | c_state char(2), 232 | c_zip char(9), 233 | c_phone char(16), 234 | c_since ]] .. datetime_type .. [[, 235 | c_credit char(2), 236 | c_credit_lim bigint, 237 | c_discount float8, 238 | c_balance float8, 239 | c_ytd_payment float8, 240 | c_payment_cnt smallint, 241 | c_delivery_cnt smallint, 242 | c_data text, 243 | PRIMARY KEY(c_w_id, c_d_id, c_id) 244 | ) %s %s]], 245 | table_num, engine_def, extra_table_options) 246 | else 247 | query = string.format([[ 248 | create table IF NOT EXISTS customer%d ( 249 | c_id int not null, 250 | c_d_id ]] .. tinyint_type .. [[ not null, 251 | c_w_id smallint not null, 252 | c_first varchar(16), 253 | c_middle char(2), 254 | c_last varchar(16), 255 | c_street_1 varchar(20), 256 | c_street_2 varchar(20), 257 | c_city varchar(20), 258 | c_state char(2), 259 | c_zip char(9), 260 | c_phone char(16), 261 | c_since ]] .. datetime_type .. [[, 262 | c_credit char(2), 263 | c_credit_lim bigint, 264 | c_discount decimal(4,2), 265 | c_balance decimal(12,2), 266 | c_ytd_payment decimal(12,2), 267 | c_payment_cnt smallint, 268 | c_delivery_cnt smallint, 269 | c_data text, 270 | PRIMARY KEY(c_w_id, c_d_id, c_id) 271 | ) %s %s]], 272 | table_num, engine_def, extra_table_options) 273 | end 274 | 275 | con:query(query) 276 | 277 | -- HISTORY TABLE 278 | local hist_auto_inc="" 279 | local hist_pk="" 280 | if sysbench.opt.force_pk == 1 then 281 | hist_auto_inc="id int NOT NULL AUTO_INCREMENT," 282 | hist_pk=",PRIMARY KEY(id)" 283 | end 284 | 285 | if drv:name() == "pgsql" 286 | then 287 | query = string.format([[ 288 | create table IF NOT EXISTS history%d ( 289 | %s 290 | h_c_id int, 291 | h_c_d_id ]] .. tinyint_type .. [[, 292 | h_c_w_id smallint, 293 | h_d_id ]] .. tinyint_type .. [[, 294 | h_w_id smallint, 295 | h_date ]] .. datetime_type .. [[, 296 | h_amount float8, 297 | h_data varchar(24) %s 298 | ) %s %s]], 299 | table_num, hist_auto_inc, hist_pk, engine_def, extra_table_options) 300 | else 301 | query = string.format([[ 302 | create table IF NOT EXISTS history%d ( 303 | %s 304 | h_c_id int, 305 | h_c_d_id ]] .. tinyint_type .. [[, 306 | h_c_w_id smallint, 307 | h_d_id ]] .. tinyint_type .. [[, 308 | h_w_id smallint, 309 | h_date ]] .. datetime_type .. [[, 310 | h_amount decimal(6,2), 311 | h_data varchar(24) %s 312 | ) %s %s]], 313 | table_num, hist_auto_inc, hist_pk, engine_def, extra_table_options) 314 | end 315 | 316 | con:query(query) 317 | 318 | query = string.format([[ 319 | create table IF NOT EXISTS orders%d ( 320 | o_id int not null, 321 | o_d_id ]] .. tinyint_type .. [[ not null, 322 | o_w_id smallint not null, 323 | o_c_id int, 324 | o_entry_d ]] .. datetime_type .. [[, 325 | o_carrier_id ]] .. tinyint_type .. [[, 326 | o_ol_cnt ]] .. tinyint_type .. [[, 327 | o_all_local ]] .. tinyint_type .. [[, 328 | PRIMARY KEY(o_w_id, o_d_id, o_id) 329 | ) %s %s]], 330 | table_num, engine_def, extra_table_options) 331 | 332 | con:query(query) 333 | 334 | -- NEW_ORDER table 335 | 336 | query = string.format([[ 337 | create table IF NOT EXISTS new_orders%d ( 338 | no_o_id int not null, 339 | no_d_id ]] .. tinyint_type .. [[ not null, 340 | no_w_id smallint not null, 341 | PRIMARY KEY(no_w_id, no_d_id, no_o_id) 342 | ) %s %s]], 343 | table_num, engine_def, extra_table_options) 344 | 345 | con:query(query) 346 | 347 | if drv:name() == "pgsql" 348 | then 349 | query = string.format([[ 350 | create table IF NOT EXISTS order_line%d ( 351 | ol_o_id int not null, 352 | ol_d_id ]] .. tinyint_type .. [[ not null, 353 | ol_w_id smallint not null, 354 | ol_number ]] .. tinyint_type .. [[ not null, 355 | ol_i_id int, 356 | ol_supply_w_id smallint, 357 | ol_delivery_d ]] .. datetime_type .. [[, 358 | ol_quantity ]] .. tinyint_type .. [[, 359 | ol_amount float8, 360 | ol_dist_info char(24), 361 | PRIMARY KEY(ol_w_id, ol_d_id, ol_o_id, ol_number) 362 | ) %s %s]], 363 | table_num, engine_def, extra_table_options) 364 | else 365 | query = string.format([[ 366 | create table IF NOT EXISTS order_line%d ( 367 | ol_o_id int not null, 368 | ol_d_id ]] .. tinyint_type .. [[ not null, 369 | ol_w_id smallint not null, 370 | ol_number ]] .. tinyint_type .. [[ not null, 371 | ol_i_id int, 372 | ol_supply_w_id smallint, 373 | ol_delivery_d ]] .. datetime_type .. [[, 374 | ol_quantity ]] .. tinyint_type .. [[, 375 | ol_amount decimal(6,2), 376 | ol_dist_info char(24), 377 | PRIMARY KEY(ol_w_id, ol_d_id, ol_o_id, ol_number) 378 | ) %s %s]], 379 | table_num, engine_def, extra_table_options) 380 | end 381 | 382 | con:query(query) 383 | 384 | -- STOCK table 385 | 386 | if drv:name() == "pgsql" 387 | then 388 | query = string.format([[ 389 | create table IF NOT EXISTS stock%d ( 390 | s_i_id int not null, 391 | s_w_id smallint not null, 392 | s_quantity smallint, 393 | s_dist_01 char(24), 394 | s_dist_02 char(24), 395 | s_dist_03 char(24), 396 | s_dist_04 char(24), 397 | s_dist_05 char(24), 398 | s_dist_06 char(24), 399 | s_dist_07 char(24), 400 | s_dist_08 char(24), 401 | s_dist_09 char(24), 402 | s_dist_10 char(24), 403 | s_ytd float8, 404 | s_order_cnt smallint, 405 | s_remote_cnt smallint, 406 | s_data varchar(50), 407 | PRIMARY KEY(s_w_id, s_i_id) 408 | ) %s %s]], 409 | table_num, engine_def, extra_table_options) 410 | else 411 | query = string.format([[ 412 | create table IF NOT EXISTS stock%d ( 413 | s_i_id int not null, 414 | s_w_id smallint not null, 415 | s_quantity smallint, 416 | s_dist_01 char(24), 417 | s_dist_02 char(24), 418 | s_dist_03 char(24), 419 | s_dist_04 char(24), 420 | s_dist_05 char(24), 421 | s_dist_06 char(24), 422 | s_dist_07 char(24), 423 | s_dist_08 char(24), 424 | s_dist_09 char(24), 425 | s_dist_10 char(24), 426 | s_ytd decimal(8,0), 427 | s_order_cnt smallint, 428 | s_remote_cnt smallint, 429 | s_data varchar(50), 430 | PRIMARY KEY(s_w_id, s_i_id) 431 | ) %s %s]], 432 | table_num, engine_def, extra_table_options) 433 | end 434 | 435 | con:query(query) 436 | 437 | local i = table_num 438 | 439 | if drv:name() == "pgsql" 440 | then 441 | query = string.format([[ 442 | create table IF NOT EXISTS item%d ( 443 | i_id int not null, 444 | i_im_id int, 445 | i_name varchar(24), 446 | i_price float8, 447 | i_data varchar(50), 448 | PRIMARY KEY(i_id) 449 | ) %s %s]], 450 | i, engine_def, extra_table_options) 451 | else 452 | query = string.format([[ 453 | create table IF NOT EXISTS item%d ( 454 | i_id int not null, 455 | i_im_id int, 456 | i_name varchar(24), 457 | i_price decimal(5,2), 458 | i_data varchar(50), 459 | PRIMARY KEY(i_id) 460 | ) %s %s]], 461 | i, engine_def, extra_table_options) 462 | end 463 | 464 | con:query(query) 465 | 466 | con:bulk_insert_init("INSERT INTO item" .. i .." (i_id, i_im_id, i_name, i_price, i_data) values") 467 | for j = 1 , MAXITEMS do 468 | local i_im_id = sysbench.rand.uniform(1,10000) 469 | local i_price = sysbench.rand.uniform_double()*100+1 470 | -- i_name is not generated as prescribed by standard, but we want to provide a better compression 471 | local i_name = string.format("item-%d-%f-%s", i_im_id, i_price, sysbench.rand.string("@@@@@")) 472 | local i_data = string.format("data-%s-%s", i_name, sysbench.rand.string("@@@@@")) 473 | 474 | query = string.format([[(%d,%d,'%s',%f,'%s')]], 475 | j, i_im_id, i_name:sub(1,24), i_price, i_data:sub(1,50)) 476 | con:bulk_insert_next(query) 477 | 478 | end 479 | con:bulk_insert_done() 480 | 481 | print(string.format("Adding indexes %d ... \n", i)) 482 | -- con:query("CREATE INDEX idx_customer"..i.." ON customer"..i.." (c_w_id,c_d_id,c_last,c_first)") 483 | -- con:query("CREATE INDEX idx_orders"..i.." ON orders"..i.." (o_w_id,o_d_id,o_c_id,o_id)") 484 | -- con:query("CREATE INDEX fkey_stock_2"..i.." ON stock"..i.." (s_i_id)") 485 | -- con:query("CREATE INDEX fkey_order_line_2"..i.." ON order_line"..i.." (ol_supply_w_id,ol_i_id)") 486 | -- con:query("CREATE INDEX fkey_history_1"..i.." ON history"..i.." (h_c_w_id,h_c_d_id,h_c_id)") 487 | -- con:query("CREATE INDEX fkey_history_2"..i.." ON history"..i.." (h_w_id,h_d_id )") 488 | con:query("CREATE INDEX idx_customer"..i.." ON customer"..i.." (c_w_id,c_d_id,c_last,c_first) "..extra_index_options) 489 | con:query("CREATE INDEX idx_orders"..i.." ON orders"..i.." (o_w_id,o_d_id,o_c_id,o_id) "..extra_index_options) 490 | con:query("CREATE INDEX fkey_stock_2"..i.." ON stock"..i.." (s_i_id) "..extra_index_options) 491 | con:query("CREATE INDEX fkey_order_line_2"..i.." ON order_line"..i.." (ol_supply_w_id,ol_i_id) "..extra_index_options) 492 | con:query("CREATE INDEX fkey_history_1"..i.." ON history"..i.." (h_c_w_id,h_c_d_id,h_c_id) "..extra_index_options) 493 | con:query("CREATE INDEX fkey_history_2"..i.." ON history"..i.." (h_w_id,h_d_id ) "..extra_index_options) 494 | if sysbench.opt.use_fk == 1 then 495 | print(string.format("Adding FK %d ... \n", i)) 496 | con:query("ALTER TABLE new_orders"..i.." ADD CONSTRAINT fkey_new_orders_1_"..table_num.." FOREIGN KEY(no_w_id,no_d_id,no_o_id) REFERENCES orders"..i.."(o_w_id,o_d_id,o_id)") 497 | con:query("ALTER TABLE orders"..i.." ADD CONSTRAINT fkey_orders_1_"..table_num.." FOREIGN KEY(o_w_id,o_d_id,o_c_id) REFERENCES customer"..i.."(c_w_id,c_d_id,c_id)") 498 | con:query("ALTER TABLE customer"..i.." ADD CONSTRAINT fkey_customer_1_"..table_num.." FOREIGN KEY(c_w_id,c_d_id) REFERENCES district"..i.."(d_w_id,d_id)") 499 | con:query("ALTER TABLE history"..i.." ADD CONSTRAINT fkey_history_1_"..table_num.." FOREIGN KEY(h_c_w_id,h_c_d_id,h_c_id) REFERENCES customer"..i.."(c_w_id,c_d_id,c_id)") 500 | con:query("ALTER TABLE history"..i.." ADD CONSTRAINT fkey_history_2_"..table_num.." FOREIGN KEY(h_w_id,h_d_id) REFERENCES district"..i.."(d_w_id,d_id)") 501 | con:query("ALTER TABLE district"..i.." ADD CONSTRAINT fkey_district_1_"..table_num.." FOREIGN KEY(d_w_id) REFERENCES warehouse"..i.."(w_id)") 502 | con:query("ALTER TABLE order_line"..i.." ADD CONSTRAINT fkey_order_line_1_"..table_num.." FOREIGN KEY(ol_w_id,ol_d_id,ol_o_id) REFERENCES orders"..i.."(o_w_id,o_d_id,o_id)") 503 | con:query("ALTER TABLE order_line"..i.." ADD CONSTRAINT fkey_order_line_2_"..table_num.." FOREIGN KEY(ol_supply_w_id,ol_i_id) REFERENCES stock"..i.."(s_w_id,s_i_id)") 504 | con:query("ALTER TABLE stock"..i.." ADD CONSTRAINT fkey_stock_1_"..table_num.." FOREIGN KEY(s_w_id) REFERENCES warehouse"..i.."(w_id)") 505 | con:query("ALTER TABLE stock"..i.." ADD CONSTRAINT fkey_stock_2_"..table_num.." FOREIGN KEY(s_i_id) REFERENCES item"..i.."(i_id)") 506 | end 507 | 508 | end 509 | 510 | 511 | function set_isolation_level(drv,con) 512 | if drv:name() == "mysql" 513 | then 514 | if sysbench.opt.trx_level == "RR" then 515 | isolation_level="REPEATABLE-READ" 516 | elseif sysbench.opt.trx_level == "RC" then 517 | isolation_level="READ-COMMITTED" 518 | elseif sysbench.opt.trx_level == "SER" then 519 | isolation_level="SERIALIZABLE" 520 | end 521 | 522 | isolation_variable=con:query_row("SHOW VARIABLES LIKE 't%_isolation'") 523 | 524 | con:query("SET SESSION " .. isolation_variable .. "='".. isolation_level .."'") 525 | end 526 | 527 | if drv:name() == "pgsql" 528 | then 529 | if sysbench.opt.trx_level == "RR" then 530 | isolation_level="REPEATABLE READ" 531 | elseif sysbench.opt.trx_level == "RC" then 532 | isolation_level="READ COMMITTED" 533 | elseif sysbench.opt.trx_level == "SER" then 534 | isolation_level="SERIALIZABLE" 535 | end 536 | 537 | con:query("SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL " .. isolation_level ) 538 | end 539 | 540 | end 541 | 542 | 543 | 544 | function load_tables(drv, con, warehouse_num) 545 | local id_index_def, id_def 546 | local engine_def = "" 547 | local extra_table_options = "" 548 | local query 549 | 550 | set_isolation_level(drv,con) 551 | 552 | -- print(string.format("Creating warehouse: %d\n", warehouse_num)) 553 | 554 | for table_num = 1, sysbench.opt.tables do 555 | 556 | print(string.format("loading tables: %d for warehouse: %d\n", table_num, warehouse_num)) 557 | 558 | con:bulk_insert_init("INSERT INTO warehouse" .. table_num .. 559 | " (w_id, w_name, w_street_1, w_street_2, w_city, w_state, w_zip, w_tax, w_ytd) values") 560 | 561 | query = string.format([[(%d, '%s','%s','%s', '%s', '%s', '%s', %f,300000)]], 562 | warehouse_num, sysbench.rand.string("name-@@@@@"), sysbench.rand.string("street1-@@@@@@@@@@"), 563 | sysbench.rand.string("street2-@@@@@@@@@@"), sysbench.rand.string("city-@@@@@@@@@@"), 564 | sysbench.rand.string("@@"),sysbench.rand.string("zip-#####"),sysbench.rand.uniform_double()*0.2 ) 565 | con:bulk_insert_next(query) 566 | 567 | con:bulk_insert_done() 568 | 569 | con:bulk_insert_init("INSERT INTO district" .. table_num .. 570 | " (d_id, d_w_id, d_name, d_street_1, d_street_2, d_city, d_state, d_zip, d_tax, d_ytd, d_next_o_id) values") 571 | 572 | for d_id = 1 , DIST_PER_WARE do 573 | 574 | query = string.format([[(%d, %d, '%s','%s','%s', '%s', '%s', '%s', %f,30000,3001)]], 575 | d_id, warehouse_num, sysbench.rand.string("name-@@@@@"), sysbench.rand.string("street1-@@@@@@@@@@"), 576 | sysbench.rand.string("street2-@@@@@@@@@@"), sysbench.rand.string("city-@@@@@@@@@@"), 577 | sysbench.rand.string("@@"),sysbench.rand.string("zip-#####"),sysbench.rand.uniform_double()*0.2 ) 578 | con:bulk_insert_next(query) 579 | 580 | end 581 | con:bulk_insert_done() 582 | 583 | -- CUSTOMER TABLE 584 | 585 | con:bulk_insert_init("INSERT INTO customer" .. table_num .. [[ 586 | (c_id, c_d_id, c_w_id, c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, 587 | c_phone, c_since, c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_payment_cnt, c_delivery_cnt, 588 | c_data) values]]) 589 | 590 | for d_id = 1 , DIST_PER_WARE do 591 | for c_id = 1 , CUST_PER_DIST do 592 | local c_last 593 | 594 | if c_id <= 1000 then 595 | c_last = Lastname(c_id - 1) 596 | else 597 | c_last = Lastname(NURand(255, 0, 999)) 598 | end 599 | 600 | query = string.format([[(%d, %d, %d, '%s','OE','%s','%s', '%s', '%s', '%s', '%s','%s',NOW(),'%s',50000,%f,-10,10,1,0,'%s' )]], 601 | c_id, d_id, warehouse_num, 602 | sysbench.rand.string("first-"..string.rep("@",sysbench.rand.uniform(2,10))), 603 | c_last, 604 | sysbench.rand.string("street1-@@@@@@@@@@"), 605 | sysbench.rand.string("street2-@@@@@@@@@@"), sysbench.rand.string("city-@@@@@@@@@@"), 606 | sysbench.rand.string("@@"),sysbench.rand.string("zip-#####"), 607 | sysbench.rand.string(string.rep("#",16)), 608 | (sysbench.rand.uniform(1,100) > 10) and "GC" or "BC", 609 | sysbench.rand.uniform_double()*0.5, 610 | string.rep(sysbench.rand.string("@"),sysbench.rand.uniform(300,500)) 611 | 612 | ) 613 | con:bulk_insert_next(query) 614 | 615 | end 616 | end 617 | 618 | con:bulk_insert_done() 619 | 620 | -- HISTORY TABLE 621 | 622 | con:bulk_insert_init("INSERT INTO history" .. table_num .. [[ 623 | (h_c_id, h_c_d_id, h_c_w_id, h_d_id, h_w_id, h_date, h_amount, h_data) values]]) 624 | 625 | for d_id = 1 , DIST_PER_WARE do 626 | for c_id = 1 , CUST_PER_DIST do 627 | 628 | query = string.format([[(%d, %d, %d, %d, %d, NOW(), 10, '%s' )]], 629 | c_id, d_id, warehouse_num, d_id, warehouse_num, 630 | string.rep(sysbench.rand.string("@"),sysbench.rand.uniform(12,24)) 631 | ) 632 | con:bulk_insert_next(query) 633 | 634 | end 635 | end 636 | 637 | con:bulk_insert_done() 638 | 639 | local tab = {} 640 | local a_counts = {} 641 | 642 | for i = 1, 3000 do 643 | tab[i] = i 644 | end 645 | 646 | for i = 1, 3000 do 647 | local j = math.random(i, 3000) 648 | tab[i], tab[j] = tab[j], tab[i] 649 | end 650 | 651 | con:bulk_insert_init("INSERT INTO orders" .. table_num .. [[ 652 | (o_id, o_d_id, o_w_id, o_c_id, o_entry_d, o_carrier_id, o_ol_cnt, o_all_local) values]]) 653 | 654 | a_counts[warehouse_num] = {} 655 | 656 | for d_id = 1 , DIST_PER_WARE do 657 | a_counts[warehouse_num][d_id] = {} 658 | for o_id = 1 , 3000 do 659 | -- 3,000 rows in the ORDER table with 660 | a_counts[warehouse_num][d_id][o_id] = sysbench.rand.uniform(5,15) 661 | 662 | query = string.format([[(%d, %d, %d, %d, NOW(), %s, %d, 1 )]], 663 | o_id, d_id, warehouse_num, tab[o_id], 664 | o_id < 2101 and sysbench.rand.uniform(1,10) or "NULL", 665 | a_counts[warehouse_num][d_id][o_id] 666 | ) 667 | con:bulk_insert_next(query) 668 | 669 | end 670 | end 671 | 672 | con:bulk_insert_done() 673 | 674 | -- STOCK table 675 | 676 | con:bulk_insert_init("INSERT INTO stock" .. table_num .. 677 | " (s_i_id, s_w_id, s_quantity, s_dist_01, s_dist_02, s_dist_03, s_dist_04, s_dist_05, s_dist_06, ".. 678 | " s_dist_07, s_dist_08, s_dist_09, s_dist_10, s_ytd, s_order_cnt, s_remote_cnt, s_data) values") 679 | 680 | for s_id = 1 , 100000 do 681 | 682 | query = string.format([[(%d, %d, %d,'%s','%s','%s','%s','%s','%s','%s','%s','%s','%s',0,0,0,'%s')]], 683 | s_id, warehouse_num, sysbench.rand.uniform(10,100), 684 | string.rep(sysbench.rand.string("@"),24), 685 | string.rep(sysbench.rand.string("@"),24), 686 | string.rep(sysbench.rand.string("@"),24), 687 | string.rep(sysbench.rand.string("@"),24), 688 | string.rep(sysbench.rand.string("@"),24), 689 | string.rep(sysbench.rand.string("@"),24), 690 | string.rep(sysbench.rand.string("@"),24), 691 | string.rep(sysbench.rand.string("@"),24), 692 | string.rep(sysbench.rand.string("@"),24), 693 | string.rep(sysbench.rand.string("@"),24), 694 | string.rep(sysbench.rand.string("@"),sysbench.rand.uniform(26,50))) 695 | con:bulk_insert_next(query) 696 | 697 | end 698 | con:bulk_insert_done() 699 | 700 | con:query(string.format("INSERT INTO new_orders%d (no_o_id, no_d_id, no_w_id) SELECT o_id, o_d_id, o_w_id FROM orders%d WHERE o_id>2100 and o_w_id=%d", table_num, table_num, warehouse_num)) 701 | 702 | con:bulk_insert_init("INSERT INTO order_line" .. table_num .. [[ 703 | (ol_o_id, ol_d_id, ol_w_id, ol_number, ol_i_id, ol_supply_w_id, ol_delivery_d, 704 | ol_quantity, ol_amount, ol_dist_info ) values]]) 705 | 706 | for d_id = 1 , DIST_PER_WARE do 707 | for o_id = 1 , 3000 do 708 | for ol_id = 1, a_counts[warehouse_num][d_id][o_id] do 709 | 710 | query = string.format([[(%d, %d, %d, %d, %d, %d, %s, 5, %f, '%s' )]], 711 | o_id, d_id, warehouse_num, ol_id, sysbench.rand.uniform(1, MAXITEMS), warehouse_num, 712 | o_id < 2101 and "NOW()" or "NULL", 713 | o_id < 2101 and 0 or sysbench.rand.uniform_double()*9999.99, 714 | string.rep(sysbench.rand.string("@"),24) 715 | ) 716 | res=con:bulk_insert_next(query) 717 | 718 | end 719 | end 720 | end 721 | 722 | con:bulk_insert_done() 723 | 724 | end 725 | 726 | end 727 | 728 | function thread_init() 729 | drv = sysbench.sql.driver() 730 | con = drv:connect() 731 | con:query("SET AUTOCOMMIT=0") 732 | 733 | end 734 | 735 | function thread_done() 736 | con:disconnect() 737 | end 738 | 739 | function cleanup() 740 | local drv = sysbench.sql.driver() 741 | local con = drv:connect() 742 | 743 | if drv:name() == "mysql" then 744 | con:query("SET FOREIGN_KEY_CHECKS=0") 745 | end 746 | 747 | for i = 1, sysbench.opt.tables do 748 | print(string.format("Dropping tables '%d'...", i)) 749 | con:query("DROP TABLE IF EXISTS history" .. i ) 750 | con:query("DROP TABLE IF EXISTS new_orders" .. i ) 751 | con:query("DROP TABLE IF EXISTS order_line" .. i ) 752 | con:query("DROP TABLE IF EXISTS orders" .. i ) 753 | con:query("DROP TABLE IF EXISTS customer" .. i ) 754 | con:query("DROP TABLE IF EXISTS district" .. i ) 755 | con:query("DROP TABLE IF EXISTS stock" .. i ) 756 | con:query("DROP TABLE IF EXISTS item" .. i ) 757 | con:query("DROP TABLE IF EXISTS warehouse" .. i ) 758 | end 759 | end 760 | 761 | function Lastname(num) 762 | local n = {"BAR", "OUGHT", "ABLE", "PRI", "PRES", "ESE", "ANTI", "CALLY", "ATION", "EING"} 763 | 764 | name =n[math.floor(num / 100) + 1] .. n[ math.floor(num / 10)%10 + 1] .. n[num%10 + 1] 765 | 766 | return name 767 | end 768 | 769 | local init_rand=1 770 | local C_255 771 | local C_1023 772 | local C_8191 773 | 774 | function NURand (A, x, y) 775 | local C 776 | 777 | if init_rand 778 | then 779 | C_255 = sysbench.rand.uniform(0, 255) 780 | C_1023 = sysbench.rand.uniform(0, 1023) 781 | C_8191 = sysbench.rand.uniform(0, 8191) 782 | init_rand = 0 783 | end 784 | 785 | if A==255 786 | then 787 | C = C_255 788 | elseif A==1023 789 | then 790 | C = C_1023 791 | elseif A==8191 792 | then 793 | C = C_8191 794 | end 795 | 796 | -- return ((( sysbench.rand.uniform(0, A) | sysbench.rand.uniform(x, y)) + C) % (y-x+1)) + x; 797 | return ((( bit.bor(sysbench.rand.uniform(0, A), sysbench.rand.uniform(x, y))) + C) % (y-x+1)) + x; 798 | end 799 | 800 | -- vim:ts=4 ss=4 sw=4 expandtab 801 | -------------------------------------------------------------------------------- /tpcc_common.lua.old: -------------------------------------------------------------------------------- 1 | -- Copyright (C) 2006-2017 Vadim Tkachenko, Percona 2 | 3 | -- This program is free software; you can redistribute it and/or modify 4 | -- it under the terms of the GNU General Public License as published by 5 | -- the Free Software Foundation; either version 2 of the License, or 6 | -- (at your option) any later version. 7 | 8 | -- This program is distributed in the hope that it will be useful, 9 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | -- GNU General Public License for more details. 12 | 13 | -- You should have received a copy of the GNU General Public License 14 | -- along with this program; if not, write to the Free Software 15 | -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 16 | 17 | -- ----------------------------------------------------------------------------- 18 | -- Common code for TPCC benchmarks. 19 | -- ----------------------------------------------------------------------------- 20 | 21 | ffi = require("ffi") 22 | 23 | ffi.cdef[[ 24 | void sb_counter_inc(int, sb_counter_type); 25 | typedef uint32_t useconds_t; 26 | int usleep(useconds_t useconds); 27 | ]] 28 | 29 | 30 | function init() 31 | assert(event ~= nil, 32 | "this script is meant to be included by other TPCC scripts and " .. 33 | "should not be called directly.") 34 | end 35 | 36 | if sysbench.cmdline.command == nil then 37 | error("Command is required. Supported commands: prepare, run, cleanup, help") 38 | end 39 | 40 | MAXITEMS=100000 41 | DIST_PER_WARE=10 42 | CUST_PER_DIST=3000 43 | 44 | -- Command line options 45 | sysbench.cmdline.options = { 46 | scale = 47 | {"Scale factor (warehouses)", 100}, 48 | tables = 49 | {"Number of tables", 1}, 50 | use_fk = 51 | {"Use foreign keys", 1}, 52 | force_pk = 53 | {"Force using auto-inc PK on history table", 0}, 54 | trx_level = 55 | {"Transaction isolation level (RC, RR or SER)", "RR"}, 56 | enable_purge = 57 | {"Use purge transaction (yes, no)", "no"}, 58 | report_csv = 59 | {"Report output in csv (yes, no)", "no"}, 60 | mysql_storage_engine = 61 | {"Storage engine, if MySQL is used", "innodb"}, 62 | mysql_table_options = 63 | {"Extra table options, if MySQL is used. e.g. 'COLLATE latin1_bin'", ""} 64 | } 65 | 66 | function sleep(n) 67 | os.execute("sleep " .. tonumber(n)) 68 | end 69 | 70 | -- Create the tables and Prepare the dataset. This command supports parallel execution, i.e. will 71 | -- benefit from executing with --threads > 1 as long as --scale > 1 72 | function cmd_prepare() 73 | local drv = sysbench.sql.driver() 74 | local con = drv:connect() 75 | local show_query="SHOW TABLES" 76 | 77 | if drv:name() == "mysql" then 78 | con:query("SET FOREIGN_KEY_CHECKS=0") 79 | end 80 | 81 | -- create tables in parallel table per thread 82 | for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.tables, 83 | sysbench.opt.threads do 84 | create_tables(drv, con, i) 85 | end 86 | 87 | -- make sure all tables are created before we load data 88 | 89 | print("Waiting on tables 30 sec\n") 90 | sleep(30) 91 | 92 | for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.scale, 93 | sysbench.opt.threads do 94 | load_tables(drv, con, i) 95 | end 96 | 97 | end 98 | 99 | -- Check consistency 100 | -- benefit from executing with --threads > 1 as long as --scale > 1 101 | function cmd_check() 102 | local drv = sysbench.sql.driver() 103 | local con = drv:connect() 104 | 105 | for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.scale, 106 | sysbench.opt.threads do 107 | check_tables(drv, con, i) 108 | end 109 | 110 | end 111 | 112 | -- Implement parallel prepare and prewarm commands 113 | sysbench.cmdline.commands = { 114 | prepare = {cmd_prepare, sysbench.cmdline.PARALLEL_COMMAND}, 115 | check = {cmd_check, sysbench.cmdline.PARALLEL_COMMAND} 116 | } 117 | 118 | 119 | function create_tables(drv, con, table_num) 120 | local id_index_def, id_def 121 | local engine_def = "" 122 | local extra_table_options = "" 123 | local query 124 | local tinyint_type="smallint" 125 | local datetime_type="timestamp" 126 | 127 | if drv:name() == "mysql" or drv:name() == "attachsql" or 128 | drv:name() == "drizzle" 129 | then 130 | engine_def = "/*! ENGINE = " .. sysbench.opt.mysql_storage_engine .. " */" 131 | extra_table_options = sysbench.opt.mysql_table_options or "" 132 | tinyint_type="tinyint" 133 | datetime_type="datetime" 134 | end 135 | 136 | print(string.format("Creating tables: %d\n", table_num)) 137 | 138 | query = string.format([[ 139 | CREATE TABLE IF NOT EXISTS warehouse%d ( 140 | w_id smallint not null, 141 | w_name varchar(10), 142 | w_street_1 varchar(20), 143 | w_street_2 varchar(20), 144 | w_city varchar(20), 145 | w_state char(2), 146 | w_zip char(9), 147 | w_tax decimal(4,2), 148 | w_ytd decimal(12,2), 149 | primary key (w_id) 150 | ) %s %s]], 151 | table_num, engine_def, extra_table_options) 152 | 153 | con:query(query) 154 | 155 | query = string.format([[ 156 | create table IF NOT EXISTS district%d ( 157 | d_id ]] .. tinyint_type .. [[ not null, 158 | d_w_id smallint not null, 159 | d_name varchar(10), 160 | d_street_1 varchar(20), 161 | d_street_2 varchar(20), 162 | d_city varchar(20), 163 | d_state char(2), 164 | d_zip char(9), 165 | d_tax decimal(4,2), 166 | d_ytd decimal(12,2), 167 | d_next_o_id int, 168 | primary key (d_w_id, d_id) 169 | ) %s %s]], 170 | table_num, engine_def, extra_table_options) 171 | 172 | con:query(query) 173 | 174 | -- CUSTOMER TABLE 175 | 176 | query = string.format([[ 177 | create table IF NOT EXISTS customer%d ( 178 | c_id int not null, 179 | c_d_id ]] .. tinyint_type .. [[ not null, 180 | c_w_id smallint not null, 181 | c_first varchar(16), 182 | c_middle char(2), 183 | c_last varchar(16), 184 | c_street_1 varchar(20), 185 | c_street_2 varchar(20), 186 | c_city varchar(20), 187 | c_state char(2), 188 | c_zip char(9), 189 | c_phone char(16), 190 | c_since ]] .. datetime_type .. [[, 191 | c_credit char(2), 192 | c_credit_lim bigint, 193 | c_discount decimal(4,2), 194 | c_balance decimal(12,2), 195 | c_ytd_payment decimal(12,2), 196 | c_payment_cnt smallint, 197 | c_delivery_cnt smallint, 198 | c_data text, 199 | PRIMARY KEY(c_w_id, c_d_id, c_id) 200 | ) %s %s]], 201 | table_num, engine_def, extra_table_options) 202 | 203 | con:query(query) 204 | 205 | -- HISTORY TABLE 206 | local hist_auto_inc="" 207 | local hist_pk="" 208 | if sysbench.opt.force_pk == 1 then 209 | hist_auto_inc="id int NOT NULL AUTO_INCREMENT," 210 | hist_pk=",PRIMARY KEY(id)" 211 | end 212 | query = string.format([[ 213 | create table IF NOT EXISTS history%d ( 214 | %s 215 | h_c_id int, 216 | h_c_d_id ]] .. tinyint_type .. [[, 217 | h_c_w_id smallint, 218 | h_d_id ]] .. tinyint_type .. [[, 219 | h_w_id smallint, 220 | h_date ]] .. datetime_type .. [[, 221 | h_amount decimal(6,2), 222 | h_data varchar(24) %s 223 | ) %s %s]], 224 | table_num, hist_auto_inc, hist_pk, engine_def, extra_table_options) 225 | 226 | con:query(query) 227 | 228 | query = string.format([[ 229 | create table IF NOT EXISTS orders%d ( 230 | o_id int not null, 231 | o_d_id ]] .. tinyint_type .. [[ not null, 232 | o_w_id smallint not null, 233 | o_c_id int, 234 | o_entry_d ]] .. datetime_type .. [[, 235 | o_carrier_id ]] .. tinyint_type .. [[, 236 | o_ol_cnt ]] .. tinyint_type .. [[, 237 | o_all_local ]] .. tinyint_type .. [[, 238 | PRIMARY KEY(o_w_id, o_d_id, o_id) 239 | ) %s %s]], 240 | table_num, engine_def, extra_table_options) 241 | 242 | con:query(query) 243 | 244 | -- NEW_ORDER table 245 | 246 | query = string.format([[ 247 | create table IF NOT EXISTS new_orders%d ( 248 | no_o_id int not null, 249 | no_d_id ]] .. tinyint_type .. [[ not null, 250 | no_w_id smallint not null, 251 | PRIMARY KEY(no_w_id, no_d_id, no_o_id) 252 | ) %s %s]], 253 | table_num, engine_def, extra_table_options) 254 | 255 | con:query(query) 256 | 257 | query = string.format([[ 258 | create table IF NOT EXISTS order_line%d ( 259 | ol_o_id int not null, 260 | ol_d_id ]] .. tinyint_type .. [[ not null, 261 | ol_w_id smallint not null, 262 | ol_number ]] .. tinyint_type .. [[ not null, 263 | ol_i_id int, 264 | ol_supply_w_id smallint, 265 | ol_delivery_d ]] .. datetime_type .. [[, 266 | ol_quantity ]] .. tinyint_type .. [[, 267 | ol_amount decimal(6,2), 268 | ol_dist_info char(24), 269 | PRIMARY KEY(ol_w_id, ol_d_id, ol_o_id, ol_number) 270 | ) %s %s]], 271 | table_num, engine_def, extra_table_options) 272 | 273 | con:query(query) 274 | 275 | -- STOCK table 276 | 277 | query = string.format([[ 278 | create table IF NOT EXISTS stock%d ( 279 | s_i_id int not null, 280 | s_w_id smallint not null, 281 | s_quantity smallint, 282 | s_dist_01 char(24), 283 | s_dist_02 char(24), 284 | s_dist_03 char(24), 285 | s_dist_04 char(24), 286 | s_dist_05 char(24), 287 | s_dist_06 char(24), 288 | s_dist_07 char(24), 289 | s_dist_08 char(24), 290 | s_dist_09 char(24), 291 | s_dist_10 char(24), 292 | s_ytd decimal(8,0), 293 | s_order_cnt smallint, 294 | s_remote_cnt smallint, 295 | s_data varchar(50), 296 | PRIMARY KEY(s_w_id, s_i_id) 297 | ) %s %s]], 298 | table_num, engine_def, extra_table_options) 299 | 300 | con:query(query) 301 | 302 | local i = table_num 303 | 304 | query = string.format([[ 305 | create table IF NOT EXISTS item%d ( 306 | i_id int not null, 307 | i_im_id int, 308 | i_name varchar(24), 309 | i_price decimal(5,2), 310 | i_data varchar(50), 311 | PRIMARY KEY(i_id) 312 | ) %s %s]], 313 | i, engine_def, extra_table_options) 314 | 315 | con:query(query) 316 | 317 | con:bulk_insert_init("INSERT INTO item" .. i .." (i_id, i_im_id, i_name, i_price, i_data) values") 318 | for j = 1 , MAXITEMS do 319 | local i_im_id = sysbench.rand.uniform(1,10000) 320 | local i_price = sysbench.rand.uniform_double()*100+1 321 | -- i_name is not generated as prescribed by standard, but we want to provide a better compression 322 | local i_name = string.format("item-%d-%f-%s", i_im_id, i_price, sysbench.rand.string("@@@@@")) 323 | local i_data = string.format("data-%s-%s", i_name, sysbench.rand.string("@@@@@")) 324 | 325 | query = string.format([[(%d,%d,'%s',%f,'%s')]], 326 | j, i_im_id, i_name:sub(1,24), i_price, i_data:sub(1,50)) 327 | con:bulk_insert_next(query) 328 | 329 | end 330 | con:bulk_insert_done() 331 | 332 | print(string.format("Adding indexes %d ... \n", i)) 333 | con:query("CREATE INDEX idx_customer"..i.." ON customer"..i.." (c_w_id,c_d_id,c_last,c_first)") 334 | con:query("CREATE INDEX idx_orders"..i.." ON orders"..i.." (o_w_id,o_d_id,o_c_id,o_id)") 335 | con:query("CREATE INDEX fkey_stock_2"..i.." ON stock"..i.." (s_i_id)") 336 | con:query("CREATE INDEX fkey_order_line_2"..i.." ON order_line"..i.." (ol_supply_w_id,ol_i_id)") 337 | con:query("CREATE INDEX fkey_history_1"..i.." ON history"..i.." (h_c_w_id,h_c_d_id,h_c_id)") 338 | con:query("CREATE INDEX fkey_history_2"..i.." ON history"..i.." (h_w_id,h_d_id )") 339 | if sysbench.opt.use_fk == 1 then 340 | print(string.format("Adding FK %d ... \n", i)) 341 | con:query("ALTER TABLE new_orders"..i.." ADD CONSTRAINT fkey_new_orders_1_"..table_num.." FOREIGN KEY(no_w_id,no_d_id,no_o_id) REFERENCES orders"..i.."(o_w_id,o_d_id,o_id)") 342 | con:query("ALTER TABLE orders"..i.." ADD CONSTRAINT fkey_orders_1_"..table_num.." FOREIGN KEY(o_w_id,o_d_id,o_c_id) REFERENCES customer"..i.."(c_w_id,c_d_id,c_id)") 343 | con:query("ALTER TABLE customer"..i.." ADD CONSTRAINT fkey_customer_1_"..table_num.." FOREIGN KEY(c_w_id,c_d_id) REFERENCES district"..i.."(d_w_id,d_id)") 344 | con:query("ALTER TABLE history"..i.." ADD CONSTRAINT fkey_history_1_"..table_num.." FOREIGN KEY(h_c_w_id,h_c_d_id,h_c_id) REFERENCES customer"..i.."(c_w_id,c_d_id,c_id)") 345 | con:query("ALTER TABLE history"..i.." ADD CONSTRAINT fkey_history_2_"..table_num.." FOREIGN KEY(h_w_id,h_d_id) REFERENCES district"..i.."(d_w_id,d_id)") 346 | con:query("ALTER TABLE district"..i.." ADD CONSTRAINT fkey_district_1_"..table_num.." FOREIGN KEY(d_w_id) REFERENCES warehouse"..i.."(w_id)") 347 | con:query("ALTER TABLE order_line"..i.." ADD CONSTRAINT fkey_order_line_1_"..table_num.." FOREIGN KEY(ol_w_id,ol_d_id,ol_o_id) REFERENCES orders"..i.."(o_w_id,o_d_id,o_id)") 348 | con:query("ALTER TABLE order_line"..i.." ADD CONSTRAINT fkey_order_line_2_"..table_num.." FOREIGN KEY(ol_supply_w_id,ol_i_id) REFERENCES stock"..i.."(s_w_id,s_i_id)") 349 | con:query("ALTER TABLE stock"..i.." ADD CONSTRAINT fkey_stock_1_"..table_num.." FOREIGN KEY(s_w_id) REFERENCES warehouse"..i.."(w_id)") 350 | con:query("ALTER TABLE stock"..i.." ADD CONSTRAINT fkey_stock_2_"..table_num.." FOREIGN KEY(s_i_id) REFERENCES item"..i.."(i_id)") 351 | end 352 | 353 | end 354 | 355 | 356 | function set_isolation_level(drv,con) 357 | if drv:name() == "mysql" 358 | then 359 | if sysbench.opt.trx_level == "RR" then 360 | isolation_level="REPEATABLE-READ" 361 | elseif sysbench.opt.trx_level == "RC" then 362 | isolation_level="READ-COMMITTED" 363 | elseif sysbench.opt.trx_level == "SER" then 364 | isolation_level="SERIALIZABLE" 365 | end 366 | 367 | isolation_variable=con:query_row("SHOW VARIABLES LIKE 't%_isolation'") 368 | 369 | con:query("SET SESSION " .. isolation_variable .. "='".. isolation_level .."'") 370 | end 371 | 372 | if drv:name() == "pgsql" 373 | then 374 | if sysbench.opt.trx_level == "RR" then 375 | isolation_level="REPEATABLE READ" 376 | elseif sysbench.opt.trx_level == "RC" then 377 | isolation_level="READ COMMITTED" 378 | elseif sysbench.opt.trx_level == "SER" then 379 | isolation_level="SERIALIZABLE" 380 | end 381 | 382 | con:query("SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL " .. isolation_level ) 383 | end 384 | 385 | end 386 | 387 | 388 | 389 | function load_tables(drv, con, warehouse_num) 390 | local id_index_def, id_def 391 | local engine_def = "" 392 | local extra_table_options = "" 393 | local query 394 | 395 | set_isolation_level(drv,con) 396 | 397 | -- print(string.format("Creating warehouse: %d\n", warehouse_num)) 398 | 399 | for table_num = 1, sysbench.opt.tables do 400 | 401 | print(string.format("loading tables: %d for warehouse: %d\n", table_num, warehouse_num)) 402 | 403 | con:bulk_insert_init("INSERT INTO warehouse" .. table_num .. 404 | " (w_id, w_name, w_street_1, w_street_2, w_city, w_state, w_zip, w_tax, w_ytd) values") 405 | 406 | query = string.format([[(%d, '%s','%s','%s', '%s', '%s', '%s', %f,300000)]], 407 | warehouse_num, sysbench.rand.string("name-@@@@@"), sysbench.rand.string("street1-@@@@@@@@@@"), 408 | sysbench.rand.string("street2-@@@@@@@@@@"), sysbench.rand.string("city-@@@@@@@@@@"), 409 | sysbench.rand.string("@@"),sysbench.rand.string("zip-#####"),sysbench.rand.uniform_double()*0.2 ) 410 | con:bulk_insert_next(query) 411 | 412 | con:bulk_insert_done() 413 | 414 | con:bulk_insert_init("INSERT INTO district" .. table_num .. 415 | " (d_id, d_w_id, d_name, d_street_1, d_street_2, d_city, d_state, d_zip, d_tax, d_ytd, d_next_o_id) values") 416 | 417 | for d_id = 1 , DIST_PER_WARE do 418 | 419 | query = string.format([[(%d, %d, '%s','%s','%s', '%s', '%s', '%s', %f,30000,3001)]], 420 | d_id, warehouse_num, sysbench.rand.string("name-@@@@@"), sysbench.rand.string("street1-@@@@@@@@@@"), 421 | sysbench.rand.string("street2-@@@@@@@@@@"), sysbench.rand.string("city-@@@@@@@@@@"), 422 | sysbench.rand.string("@@"),sysbench.rand.string("zip-#####"),sysbench.rand.uniform_double()*0.2 ) 423 | con:bulk_insert_next(query) 424 | 425 | end 426 | con:bulk_insert_done() 427 | 428 | -- CUSTOMER TABLE 429 | 430 | con:bulk_insert_init("INSERT INTO customer" .. table_num .. [[ 431 | (c_id, c_d_id, c_w_id, c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, 432 | c_phone, c_since, c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_payment_cnt, c_delivery_cnt, 433 | c_data) values]]) 434 | 435 | for d_id = 1 , DIST_PER_WARE do 436 | for c_id = 1 , CUST_PER_DIST do 437 | local c_last 438 | 439 | if c_id <= 1000 then 440 | c_last = Lastname(c_id - 1) 441 | else 442 | c_last = Lastname(NURand(255, 0, 999)) 443 | end 444 | 445 | query = string.format([[(%d, %d, %d, '%s','OE','%s','%s', '%s', '%s', '%s', '%s','%s',NOW(),'%s',50000,%f,-10,10,1,0,'%s' )]], 446 | c_id, d_id, warehouse_num, 447 | sysbench.rand.string("first-"..string.rep("@",sysbench.rand.uniform(2,10))), 448 | c_last, 449 | sysbench.rand.string("street1-@@@@@@@@@@"), 450 | sysbench.rand.string("street2-@@@@@@@@@@"), sysbench.rand.string("city-@@@@@@@@@@"), 451 | sysbench.rand.string("@@"),sysbench.rand.string("zip-#####"), 452 | sysbench.rand.string(string.rep("#",16)), 453 | (sysbench.rand.uniform(1,100) > 10) and "GC" or "BC", 454 | sysbench.rand.uniform_double()*0.5, 455 | string.rep(sysbench.rand.string("@"),sysbench.rand.uniform(300,500)) 456 | 457 | ) 458 | con:bulk_insert_next(query) 459 | 460 | end 461 | end 462 | 463 | con:bulk_insert_done() 464 | 465 | -- HISTORY TABLE 466 | 467 | con:bulk_insert_init("INSERT INTO history" .. table_num .. [[ 468 | (h_c_id, h_c_d_id, h_c_w_id, h_d_id, h_w_id, h_date, h_amount, h_data) values]]) 469 | 470 | for d_id = 1 , DIST_PER_WARE do 471 | for c_id = 1 , CUST_PER_DIST do 472 | 473 | query = string.format([[(%d, %d, %d, %d, %d, NOW(), 10, '%s' )]], 474 | c_id, d_id, warehouse_num, d_id, warehouse_num, 475 | string.rep(sysbench.rand.string("@"),sysbench.rand.uniform(12,24)) 476 | ) 477 | con:bulk_insert_next(query) 478 | 479 | end 480 | end 481 | 482 | con:bulk_insert_done() 483 | 484 | local tab = {} 485 | local a_counts = {} 486 | 487 | for i = 1, 3000 do 488 | tab[i] = i 489 | end 490 | 491 | for i = 1, 3000 do 492 | local j = math.random(i, 3000) 493 | tab[i], tab[j] = tab[j], tab[i] 494 | end 495 | 496 | con:bulk_insert_init("INSERT INTO orders" .. table_num .. [[ 497 | (o_id, o_d_id, o_w_id, o_c_id, o_entry_d, o_carrier_id, o_ol_cnt, o_all_local) values]]) 498 | 499 | a_counts[warehouse_num] = {} 500 | 501 | for d_id = 1 , DIST_PER_WARE do 502 | a_counts[warehouse_num][d_id] = {} 503 | for o_id = 1 , 3000 do 504 | -- 3,000 rows in the ORDER table with 505 | a_counts[warehouse_num][d_id][o_id] = sysbench.rand.uniform(5,15) 506 | 507 | query = string.format([[(%d, %d, %d, %d, NOW(), %s, %d, 1 )]], 508 | o_id, d_id, warehouse_num, tab[o_id], 509 | o_id < 2101 and sysbench.rand.uniform(1,10) or "NULL", 510 | a_counts[warehouse_num][d_id][o_id] 511 | ) 512 | con:bulk_insert_next(query) 513 | 514 | end 515 | end 516 | 517 | con:bulk_insert_done() 518 | 519 | -- STOCK table 520 | 521 | con:bulk_insert_init("INSERT INTO stock" .. table_num .. 522 | " (s_i_id, s_w_id, s_quantity, s_dist_01, s_dist_02, s_dist_03, s_dist_04, s_dist_05, s_dist_06, ".. 523 | " s_dist_07, s_dist_08, s_dist_09, s_dist_10, s_ytd, s_order_cnt, s_remote_cnt, s_data) values") 524 | 525 | for s_id = 1 , 100000 do 526 | 527 | query = string.format([[(%d, %d, %d,'%s','%s','%s','%s','%s','%s','%s','%s','%s','%s',0,0,0,'%s')]], 528 | s_id, warehouse_num, sysbench.rand.uniform(10,100), 529 | string.rep(sysbench.rand.string("@"),24), 530 | string.rep(sysbench.rand.string("@"),24), 531 | string.rep(sysbench.rand.string("@"),24), 532 | string.rep(sysbench.rand.string("@"),24), 533 | string.rep(sysbench.rand.string("@"),24), 534 | string.rep(sysbench.rand.string("@"),24), 535 | string.rep(sysbench.rand.string("@"),24), 536 | string.rep(sysbench.rand.string("@"),24), 537 | string.rep(sysbench.rand.string("@"),24), 538 | string.rep(sysbench.rand.string("@"),24), 539 | string.rep(sysbench.rand.string("@"),sysbench.rand.uniform(26,50))) 540 | con:bulk_insert_next(query) 541 | 542 | end 543 | con:bulk_insert_done() 544 | 545 | con:query(string.format("INSERT INTO new_orders%d (no_o_id, no_d_id, no_w_id) SELECT o_id, o_d_id, o_w_id FROM orders%d WHERE o_id>2100 and o_w_id=%d", table_num, table_num, warehouse_num)) 546 | 547 | con:bulk_insert_init("INSERT INTO order_line" .. table_num .. [[ 548 | (ol_o_id, ol_d_id, ol_w_id, ol_number, ol_i_id, ol_supply_w_id, ol_delivery_d, 549 | ol_quantity, ol_amount, ol_dist_info ) values]]) 550 | 551 | for d_id = 1 , DIST_PER_WARE do 552 | for o_id = 1 , 3000 do 553 | for ol_id = 1, a_counts[warehouse_num][d_id][o_id] do 554 | 555 | query = string.format([[(%d, %d, %d, %d, %d, %d, %s, 5, %f, '%s' )]], 556 | o_id, d_id, warehouse_num, ol_id, sysbench.rand.uniform(1, MAXITEMS), warehouse_num, 557 | o_id < 2101 and "NOW()" or "NULL", 558 | o_id < 2101 and 0 or sysbench.rand.uniform_double()*9999.99, 559 | string.rep(sysbench.rand.string("@"),24) 560 | ) 561 | res=con:bulk_insert_next(query) 562 | 563 | end 564 | end 565 | end 566 | 567 | con:bulk_insert_done() 568 | 569 | end 570 | 571 | end 572 | 573 | function thread_init() 574 | drv = sysbench.sql.driver() 575 | con = drv:connect() 576 | con:query("SET AUTOCOMMIT=0") 577 | 578 | end 579 | 580 | function thread_done() 581 | con:disconnect() 582 | end 583 | 584 | function cleanup() 585 | local drv = sysbench.sql.driver() 586 | local con = drv:connect() 587 | 588 | if drv:name() == "mysql" then 589 | con:query("SET FOREIGN_KEY_CHECKS=0") 590 | end 591 | 592 | for i = 1, sysbench.opt.tables do 593 | print(string.format("Dropping tables '%d'...", i)) 594 | con:query("DROP TABLE IF EXISTS history" .. i ) 595 | con:query("DROP TABLE IF EXISTS new_orders" .. i ) 596 | con:query("DROP TABLE IF EXISTS order_line" .. i ) 597 | con:query("DROP TABLE IF EXISTS orders" .. i ) 598 | con:query("DROP TABLE IF EXISTS customer" .. i ) 599 | con:query("DROP TABLE IF EXISTS district" .. i ) 600 | con:query("DROP TABLE IF EXISTS stock" .. i ) 601 | con:query("DROP TABLE IF EXISTS item" .. i ) 602 | con:query("DROP TABLE IF EXISTS warehouse" .. i ) 603 | end 604 | end 605 | 606 | function Lastname(num) 607 | local n = {"BAR", "OUGHT", "ABLE", "PRI", "PRES", "ESE", "ANTI", "CALLY", "ATION", "EING"} 608 | 609 | name =n[math.floor(num / 100) + 1] .. n[ math.floor(num / 10)%10 + 1] .. n[num%10 + 1] 610 | 611 | return name 612 | end 613 | 614 | local init_rand=1 615 | local C_255 616 | local C_1023 617 | local C_8191 618 | 619 | function NURand (A, x, y) 620 | local C 621 | 622 | if init_rand 623 | then 624 | C_255 = sysbench.rand.uniform(0, 255) 625 | C_1023 = sysbench.rand.uniform(0, 1023) 626 | C_8191 = sysbench.rand.uniform(0, 8191) 627 | init_rand = 0 628 | end 629 | 630 | if A==255 631 | then 632 | C = C_255 633 | elseif A==1023 634 | then 635 | C = C_1023 636 | elseif A==8191 637 | then 638 | C = C_8191 639 | end 640 | 641 | -- return ((( sysbench.rand.uniform(0, A) | sysbench.rand.uniform(x, y)) + C) % (y-x+1)) + x; 642 | return ((( bit.bor(sysbench.rand.uniform(0, A), sysbench.rand.uniform(x, y))) + C) % (y-x+1)) + x; 643 | end 644 | 645 | -- vim:ts=4 ss=4 sw=4 expandtab 646 | -------------------------------------------------------------------------------- /tpcc_run.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sysbench 2 | 3 | -- This program is free software; you can redistribute it and/or modify 4 | -- it under the terms of the GNU General Public License as published by 5 | -- the Free Software Foundation; either version 2 of the License, or 6 | -- (at your option) any later version. 7 | 8 | -- This program is distributed in the hope that it will be useful, 9 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | -- GNU General Public License for more details. 12 | 13 | -- You should have received a copy of the GNU General Public License 14 | -- along with this program; if not, write to the Free Software 15 | -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 16 | 17 | -- ---------------------------------------------------------------------- 18 | -- TPCC-like workload 19 | -- ---------------------------------------------------------------------- 20 | 21 | require("tpcc_common") 22 | 23 | 24 | -- 25 | -- produce the id of a valid warehouse other than home_ware 26 | -- (assuming there is one) 27 | -- 28 | function other_ware (home_ware) 29 | local tmp 30 | 31 | if sysbench.opt.scale == 1 then return home_ware end 32 | repeat 33 | tmp = sysbench.rand.uniform(1, sysbench.opt.scale) 34 | until tmp == home_ware 35 | return tmp 36 | end 37 | 38 | function new_order() 39 | 40 | -- prep work 41 | 42 | local table_num = sysbench.rand.uniform(1, sysbench.opt.tables) 43 | local w_id = sysbench.rand.uniform(1, sysbench.opt.scale) 44 | local d_id = sysbench.rand.uniform(1, DIST_PER_WARE) 45 | local c_id = NURand(1023, 1, CUST_PER_DIST) 46 | 47 | local ol_cnt = sysbench.rand.uniform(5, 15); 48 | local rbk = sysbench.rand.uniform(1, 100); 49 | local itemid = {} 50 | local supware = {} 51 | local qty = {} 52 | local all_local = 1 53 | 54 | for i = 1, ol_cnt 55 | do 56 | itemid[i] = NURand(8191, 1, MAXITEMS) 57 | if ((i == ol_cnt - 1) and (rbk == 1)) 58 | then 59 | itemid[i] = -1 60 | end 61 | if sysbench.rand.uniform(1, 100) ~= 1 62 | then 63 | supware[i] = w_id 64 | else 65 | supware[i] = other_ware(w_id) 66 | all_local = 0 67 | end 68 | qty[i] = sysbench.rand.uniform(1, 10) 69 | end 70 | 71 | 72 | -- SELECT c_discount, c_last, c_credit, w_tax 73 | -- INTO :c_discount, :c_last, :c_credit, :w_tax 74 | -- FROM customer, warehouse 75 | -- WHERE w_id = :w_id 76 | -- AND c_w_id = w_id 77 | -- AND c_d_id = :d_id 78 | -- AND c_id = :c_id; 79 | 80 | con:query("BEGIN") 81 | 82 | local c_discount 83 | local c_last 84 | local c_credit 85 | local w_tax 86 | 87 | c_discount, c_last, c_credit, w_tax = con:query_row(([[execute p_new_order1_%d(%d,%d,%d)]]):format(table_num, w_id, d_id, c_id)) 88 | -- c_discount, c_last, c_credit, w_tax = con:query_row(([[SELECT c_discount, c_last, c_credit, w_tax 89 | -- FROM customer%d, warehouse%d 90 | -- WHERE w_id = %d 91 | -- AND c_w_id = w_id 92 | -- AND c_d_id = %d 93 | -- AND c_id = %d]]): 94 | -- format(table_num, table_num, w_id, d_id, c_id)) 95 | 96 | -- SELECT d_next_o_id, d_tax INTO :d_next_o_id, :d_tax 97 | -- FROM district 98 | -- WHERE d_id = :d_id 99 | -- AND d_w_id = :w_id 100 | -- FOR UPDATE 101 | local d_next_o_id 102 | local d_tax 103 | 104 | d_next_o_id, d_tax = con:query_row(([[execute p_new_order2_%d(%d,%d)]]):format(table_num, w_id, d_id)) 105 | -- d_next_o_id, d_tax = con:query_row(([[SELECT d_next_o_id, d_tax 106 | -- FROM district%d 107 | -- WHERE d_w_id = %d 108 | -- AND d_id = %d FOR UPDATE]]): 109 | -- format(table_num, w_id, d_id)) 110 | 111 | -- UPDATE district SET d_next_o_id = :d_next_o_id + 1 112 | -- WHERE d_id = :d_id 113 | -- AND d_w_id = :w_id; 114 | 115 | con:query(([[execute p_new_order3_%d(%d,%d,%d)]]):format(table_num, d_next_o_id + 1, d_id, w_id)) 116 | -- con:query(([[UPDATE district%d 117 | -- SET d_next_o_id = %d 118 | -- WHERE d_id = %d AND d_w_id= %d]]):format(table_num, d_next_o_id + 1, d_id, w_id)) 119 | 120 | --INSERT INTO orders (o_id, o_d_id, o_w_id, o_c_id, 121 | -- o_entry_d, o_ol_cnt, o_all_local) 122 | -- VALUES(:o_id, :d_id, :w_id, :c_id, 123 | -- :datetime, 124 | -- :o_ol_cnt, :o_all_local); 125 | 126 | con:query(([[execute p_new_order4_%d(%d,%d,%d,%d,%d,%d)]]):format(table_num, d_next_o_id, d_id, w_id, c_id, ol_cnt, all_local)) 127 | -- con:query(([[INSERT INTO orders%d 128 | -- (o_id, o_d_id, o_w_id, o_c_id, o_entry_d, o_ol_cnt, o_all_local) 129 | -- VALUES (%d,%d,%d,%d,NOW(),%d,%d)]]): 130 | -- format(table_num, d_next_o_id, d_id, w_id, c_id, ol_cnt, all_local)) 131 | 132 | -- INSERT INTO new_orders (no_o_id, no_d_id, no_w_id) 133 | -- VALUES (:o_id,:d_id,:w_id); */ 134 | 135 | con:query(([[execute p_new_order5_%d(%d,%d,%d)]]):format(table_num, d_next_o_id, d_id, w_id)) 136 | -- con:query(([[INSERT INTO new_orders%d (no_o_id, no_d_id, no_w_id) 137 | -- VALUES (%d,%d,%d)]]): 138 | -- format(table_num, d_next_o_id, d_id, w_id)) 139 | 140 | for ol_number=1, ol_cnt do 141 | local ol_supply_w_id = supware[ol_number] 142 | local ol_i_id = itemid[ol_number] 143 | local ol_quantity = qty[ol_number] 144 | 145 | -- SELECT i_price, i_name, i_data 146 | -- INTO :i_price, :i_name, :i_data 147 | -- FROM item 148 | -- WHERE i_id = :ol_i_id;*/ 149 | 150 | rs = con:query(([[execute p_new_order6_%d(%d)]]):format(table_num, ol_i_id)) 151 | -- rs = con:query(([[SELECT i_price, i_name, i_data 152 | -- FROM item%d 153 | -- WHERE i_id = %d]]): 154 | -- format(table_num, ol_i_id)) 155 | 156 | local i_price 157 | local i_name 158 | local i_data 159 | 160 | if rs.nrows == 0 then 161 | -- print("ROLLBACK") 162 | ffi.C.sb_counter_inc(sysbench.tid, ffi.C.SB_CNT_ERROR) 163 | con:query("ROLLBACK") 164 | return 165 | end 166 | 167 | i_price, i_name, i_data = unpack(rs:fetch_row(), 1, rs.nfields) 168 | 169 | -- SELECT s_quantity, s_data, s_dist_01, s_dist_02, 170 | -- s_dist_03, s_dist_04, s_dist_05, s_dist_06, 171 | -- s_dist_07, s_dist_08, s_dist_09, s_dist_10 172 | -- INTO :s_quantity, :s_data, :s_dist_01, :s_dist_02, 173 | -- :s_dist_03, :s_dist_04, :s_dist_05, :s_dist_06, 174 | -- :s_dist_07, :s_dist_08, :s_dist_09, :s_dist_10 175 | -- FROM stock 176 | -- WHERE s_i_id = :ol_i_id 177 | -- AND s_w_id = :ol_supply_w_id 178 | -- FOR UPDATE;*/ 179 | 180 | local s_quantity 181 | local s_data 182 | local ol_dist_info 183 | 184 | s_quantity, s_data, ol_dist_info = con:query_row(([[execute p_new_order7_%d_%s(%d,%d)]]):format(table_num, string.format("%02d",d_id), ol_i_id, ol_supply_w_id)) 185 | -- s_quantity, s_data, ol_dist_info = con:query_row(([[SELECT s_quantity, s_data, s_dist_%s s_dist 186 | -- FROM stock%d 187 | -- WHERE s_i_id = %d AND s_w_id= %d FOR UPDATE]]): 188 | -- format(string.format("%02d",d_id),table_num,ol_i_id,ol_supply_w_id )) 189 | 190 | s_quantity=tonumber(s_quantity) 191 | if (s_quantity > ol_quantity) then 192 | s_quantity = s_quantity - ol_quantity 193 | else 194 | s_quantity = s_quantity - ol_quantity + 91 195 | end 196 | 197 | -- UPDATE stock SET s_quantity = :s_quantity 198 | -- WHERE s_i_id = :ol_i_id 199 | -- AND s_w_id = :ol_supply_w_id;*/ 200 | 201 | con:query(([[execute p_new_order8_%d(%d,%d,%d)]]):format(table_num, s_quantity, ol_i_id, ol_supply_w_id)) 202 | -- con:query(([[UPDATE stock%d 203 | -- SET s_quantity = %d 204 | -- WHERE s_i_id = %d 205 | -- AND s_w_id= %d]]): 206 | -- format(table_num, s_quantity, ol_i_id, ol_supply_w_id)) 207 | 208 | i_price=tonumber(i_price) 209 | w_tax=tonumber(w_tax) 210 | d_tax=tonumber(d_tax) 211 | c_discount=tonumber(c_discount) 212 | 213 | ol_amount = ol_quantity * i_price * (1 + w_tax + d_tax) * (1 - c_discount); 214 | 215 | -- INSERT INTO order_line (ol_o_id, ol_d_id, ol_w_id, 216 | -- ol_number, ol_i_id, 217 | -- ol_supply_w_id, ol_quantity, 218 | -- ol_amount, ol_dist_info) 219 | -- VALUES (:o_id, :d_id, :w_id, :ol_number, :ol_i_id, 220 | -- :ol_supply_w_id, :ol_quantity, :ol_amount, 221 | -- :ol_dist_info); 222 | con:query(([[execute p_new_order9_%d(%d,%d,%d,%d,%d,%d,%d,%d,'%s')]]):format(table_num, d_next_o_id, d_id, w_id, ol_number, ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_dist_info)) 223 | -- con:query(([[INSERT INTO order_line%d 224 | -- (ol_o_id, ol_d_id, ol_w_id, ol_number, ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_dist_info) 225 | -- VALUES (%d,%d,%d,%d,%d,%d,%d,%d,'%s')]]): 226 | -- format(table_num, d_next_o_id, d_id, w_id, ol_number, ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_dist_info)) 227 | 228 | end 229 | 230 | con:query("COMMIT") 231 | 232 | end 233 | 234 | function payment() 235 | -- prep work 236 | 237 | local table_num = sysbench.rand.uniform(1, sysbench.opt.tables) 238 | local w_id = sysbench.rand.uniform(1, sysbench.opt.scale) 239 | local d_id = sysbench.rand.uniform(1, DIST_PER_WARE) 240 | local c_id = NURand(1023, 1, CUST_PER_DIST) 241 | local h_amount = sysbench.rand.uniform(1,5000) 242 | local byname 243 | local c_w_id 244 | local c_d_id 245 | local c_last = Lastname(NURand(255,0,999)) 246 | 247 | if sysbench.rand.uniform(1, 100) <= 60 then 248 | byname = 1 -- select by last name 249 | else 250 | byname = 0 -- select by customer id 251 | end 252 | 253 | if sysbench.rand.uniform(1, 100) <= 85 then 254 | c_w_id = w_id 255 | c_d_id = d_id 256 | else 257 | c_w_id = other_ware(w_id) 258 | c_d_id = sysbench.rand.uniform(1, DIST_PER_WARE) 259 | end 260 | 261 | -- UPDATE warehouse SET w_ytd = w_ytd + :h_amount 262 | -- WHERE w_id =:w_id 263 | 264 | con:query("BEGIN") 265 | 266 | con:query(([[execute p_payment1_%d(%d,%d)]]):format(table_num, h_amount, w_id)) 267 | -- con:query(([[UPDATE warehouse%d 268 | -- SET w_ytd = w_ytd + %d 269 | -- WHERE w_id = %d]]):format(table_num, h_amount, w_id )) 270 | 271 | -- SELECT w_street_1, w_street_2, w_city, w_state, w_zip, 272 | -- w_name 273 | -- INTO :w_street_1, :w_street_2, :w_city, :w_state, 274 | -- :w_zip, :w_name 275 | -- FROM warehouse 276 | -- WHERE w_id = :w_id;*/ 277 | local w_street_1, w_street_2, w_city, w_state, w_zip, w_name 278 | 279 | w_street_1, w_street_2, w_city, w_state, w_zip, w_name = con:query_row(([[execute p_payment2_%d(%d)]]):format(table_num, w_id)) 280 | -- w_street_1, w_street_2, w_city, w_state, w_zip, w_name = 281 | -- con:query_row(([[SELECT w_street_1, w_street_2, w_city, w_state, w_zip, w_name 282 | -- FROM warehouse%d 283 | -- WHERE w_id = %d]]):format(table_num, w_id)) 284 | 285 | -- UPDATE district SET d_ytd = d_ytd + :h_amount 286 | -- WHERE d_w_id = :w_id 287 | -- AND d_id = :d_id;*/ 288 | 289 | con:query(([[execute p_payment3_%d(%d,%d,%d)]]):format(table_num, h_amount, w_id, d_id)) 290 | -- con:query(([[UPDATE district%d 291 | -- SET d_ytd = d_ytd + %d 292 | -- WHERE d_w_id = %d 293 | -- AND d_id= %d]]):format(table_num, h_amount, w_id, d_id)) 294 | 295 | 296 | local d_street_1,d_street_2, d_city, d_state, d_zip, d_name 297 | 298 | d_street_1,d_street_2, d_city, d_state, d_zip, d_name = con:query_row(([[execute p_payment4_%d(%d,%d)]]):format(table_num, w_id, d_id)) 299 | -- d_street_1,d_street_2, d_city, d_state, d_zip, d_name = 300 | -- con:query_row(([[SELECT d_street_1, d_street_2, d_city, d_state, d_zip, d_name 301 | -- FROM district%d 302 | -- WHERE d_w_id = %d 303 | -- AND d_id = %d]]):format(table_num, w_id, d_id )) 304 | 305 | if byname == 1 then 306 | 307 | -- SELECT count(c_id) 308 | -- FROM customer 309 | -- WHERE c_w_id = :c_w_id 310 | -- AND c_d_id = :c_d_id 311 | -- AND c_last = :c_last;*/ 312 | 313 | local namecnt = con:query_row(([[execute p_payment5_%d(%d,%d,'%s')]]):format(table_num, w_id, c_d_id, c_last)) 314 | -- local namecnt = con:query_row(([[SELECT count(c_id) namecnt 315 | -- FROM customer%d 316 | -- WHERE c_w_id = %d 317 | -- AND c_d_id= %d 318 | -- AND c_last='%s']]):format(table_num, w_id, c_d_id, c_last )) 319 | 320 | 321 | -- SELECT c_id 322 | -- FROM customer 323 | -- WHERE c_w_id = :c_w_id 324 | -- AND c_d_id = :c_d_id 325 | -- AND c_last = :c_last 326 | -- ORDER BY c_first; 327 | 328 | if namecnt % 2 == 0 then 329 | namecnt = namecnt + 1 330 | end 331 | 332 | rs = con:query(([[execute p_payment6_%d(%d,%d,'%s')]]):format(table_num, w_id, c_d_id, c_last)) 333 | -- rs = con:query(([[SELECT c_id 334 | -- FROM customer%d 335 | -- WHERE c_w_id = %d AND c_d_id= %d 336 | -- AND c_last='%s' ORDER BY c_first]] 337 | -- ):format(table_num, w_id, c_d_id, c_last )) 338 | 339 | for i = 1, (namecnt / 2 ) + 1 do 340 | row = rs:fetch_row() 341 | c_id = row[1] 342 | end 343 | end -- byname 344 | 345 | -- SELECT c_first, c_middle, c_last, c_street_1, 346 | -- c_street_2, c_city, c_state, c_zip, c_phone, 347 | -- c_credit, c_credit_lim, c_discount, c_balance, 348 | -- c_since 349 | -- FROM customer 350 | -- WHERE c_w_id = :c_w_id 351 | -- AND c_d_id = :c_d_id 352 | -- AND c_id = :c_id 353 | -- FOR UPDATE; 354 | 355 | local c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, 356 | c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_since 357 | 358 | c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, 359 | c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_since = 360 | con:query_row(([[execute p_payment7_%d(%d,%d,%d)]]):format(table_num, w_id, c_d_id, c_id)) 361 | 362 | -- c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, 363 | -- c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_since = 364 | -- con:query_row(([[SELECT c_first, c_middle, c_last, c_street_1, 365 | -- c_street_2, c_city, c_state, c_zip, c_phone, 366 | -- c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_since 367 | -- FROM customer%d 368 | -- WHERE c_w_id = %d 369 | -- AND c_d_id= %d 370 | -- AND c_id=%d FOR UPDATE]]) 371 | -- :format(table_num, w_id, c_d_id, c_id )) 372 | 373 | 374 | c_balance = tonumber(c_balance) - h_amount 375 | c_ytd_payment = tonumber(c_ytd_payment) + h_amount 376 | 377 | if c_credit == "BC" then 378 | -- SELECT c_data 379 | -- INTO :c_data 380 | -- FROM customer 381 | -- WHERE c_w_id = :c_w_id 382 | -- AND c_d_id = :c_d_id 383 | -- AND c_id = :c_id; */ 384 | 385 | local c_data 386 | 387 | c_data = con:query_row(([[execute p_payment8_%d(%d,%d,%d)]]):format(table_num, w_id, c_d_id, c_id)) 388 | -- c_data = con:query_row(([[SELECT c_data 389 | -- FROM customer%d 390 | -- WHERE c_w_id = %d 391 | -- AND c_d_id=%d 392 | -- AND c_id= %d]]): 393 | -- format(table_num, w_id, c_d_id, c_id )) 394 | 395 | local c_new_data=string.sub(string.format("| %4d %2d %4d %2d %4d $%7.2f %12s %24s", 396 | c_id, c_d_id, c_w_id, d_id, w_id, h_amount, os.time(), c_data), 1, 500); 397 | 398 | -- UPDATE customer 399 | -- SET c_balance = :c_balance, c_data = :c_new_data 400 | -- WHERE c_w_id = :c_w_id 401 | -- AND c_d_id = :c_d_id 402 | -- AND c_id = :c_id 403 | 404 | 405 | con:query(([[execute p_payment9_%d(%f,%f,'%s',%d,%d,%d)]]):format(table_num, c_balance, c_ytd_payment, c_new_data, w_id, c_d_id, c_id)) 406 | -- con:query(([[UPDATE customer%d 407 | -- SET c_balance=%f, c_ytd_payment=%f, c_data='%s' 408 | -- WHERE c_w_id = %d 409 | -- AND c_d_id=%d 410 | -- AND c_id=%d]]) 411 | -- :format(table_num, c_balance, c_ytd_payment, c_new_data, w_id, c_d_id, c_id )) 412 | else 413 | 414 | con:query(([[execute p_payment10_%d(%f,%f,%d,%d,%d)]]):format(table_num, c_balance, c_ytd_payment, w_id, c_d_id, c_id)) 415 | -- con:query(([[UPDATE customer%d 416 | -- SET c_balance=%f, c_ytd_payment=%f 417 | -- WHERE c_w_id = %d 418 | -- AND c_d_id=%d 419 | -- AND c_id=%d]]) 420 | -- :format(table_num, c_balance, c_ytd_payment, w_id, c_d_id, c_id )) 421 | 422 | end 423 | 424 | -- INSERT INTO history(h_c_d_id, h_c_w_id, h_c_id, h_d_id, 425 | -- h_w_id, h_date, h_amount, h_data) 426 | -- VALUES(:c_d_id, :c_w_id, :c_id, :d_id, 427 | -- :w_id, 428 | -- :datetime, 429 | -- :h_amount, :h_data);*/ 430 | 431 | con:query(([[execute p_payment11_%d(%d,%d,%d,%d,%d,%d,'%s')]]):format(table_num, c_d_id, c_w_id, c_id, d_id, w_id, h_amount, string.format("%10s %10s ",w_name,d_name))) 432 | -- con:query(([[INSERT INTO history%d 433 | -- (h_c_d_id, h_c_w_id, h_c_id, h_d_id, h_w_id, h_date, h_amount, h_data) 434 | -- VALUES (%d,%d,%d,%d,%d,NOW(),%d,'%s')]]) 435 | -- :format(table_num, c_d_id, c_w_id, c_id, d_id, w_id, h_amount, string.format("%10s %10s ",w_name,d_name))) 436 | 437 | con:query("COMMIT") 438 | 439 | end 440 | 441 | function orderstatus() 442 | 443 | local table_num = sysbench.rand.uniform(1, sysbench.opt.tables) 444 | local w_id = sysbench.rand.uniform(1, sysbench.opt.scale) 445 | local d_id = sysbench.rand.uniform(1, DIST_PER_WARE) 446 | local c_id = NURand(1023, 1, CUST_PER_DIST) 447 | local byname 448 | local c_last = Lastname(NURand(255,0,999)) 449 | 450 | if sysbench.rand.uniform(1, 100) <= 60 then 451 | byname = 1 -- select by last name 452 | else 453 | byname = 0 -- select by customer id 454 | end 455 | 456 | local c_balance 457 | local c_first 458 | local c_middle 459 | con:query("BEGIN") 460 | 461 | if byname == 1 then 462 | -- /*EXEC_SQL SELECT count(c_id) 463 | -- FROM customer 464 | -- WHERE c_w_id = :c_w_id 465 | -- AND c_d_id = :c_d_id 466 | -- AND c_last = :c_last;*/ 467 | 468 | local namecnt 469 | 470 | namecnt = con:query_row(([[execute p_orderstatus1_%d(%d,%d,'%s')]]):format(table_num, w_id, d_id, c_last)) 471 | -- namecnt = con:query_row(([[SELECT count(c_id) namecnt 472 | -- FROM customer%d 473 | -- WHERE c_w_id = %d 474 | -- AND c_d_id= %d 475 | -- AND c_last='%s']]): 476 | -- format(table_num, w_id, d_id, c_last )) 477 | 478 | 479 | -- SELECT c_balance, c_first, c_middle, c_id 480 | -- FROM customer 481 | -- WHERE c_w_id = :c_w_id 482 | -- AND c_d_id = :c_d_id 483 | -- AND c_last = :c_last 484 | -- ORDER BY c_first; 485 | 486 | rs = con:query(([[execute p_orderstatus2_%d(%d,%d,'%s')]]):format(table_num, w_id, d_id, c_last)) 487 | -- rs = con:query(([[SELECT c_balance, c_first, c_middle, c_id 488 | -- FROM customer%d 489 | -- WHERE c_w_id = %d 490 | -- AND c_d_id= %d 491 | -- AND c_last='%s' ORDER BY c_first]]) 492 | -- :format(table_num, w_id, d_id, c_last )) 493 | 494 | if namecnt % 2 == 0 then 495 | namecnt = namecnt + 1 496 | end 497 | for i = 1, (namecnt / 2 ) + 1 do 498 | row = rs:fetch_row() 499 | c_balance = row[1] 500 | c_first = row[2] 501 | c_middle = row[3] 502 | c_id = row[4] 503 | end 504 | else 505 | -- SELECT c_balance, c_first, c_middle, c_last 506 | -- FROM customer 507 | -- WHERE c_w_id = :c_w_id 508 | -- AND c_d_id = :c_d_id 509 | -- AND c_id = :c_id;*/ 510 | 511 | c_balance, c_first, c_middle, c_last = 512 | con:query_row(([[execute p_orderstatus3_%d(%d,%d,%d)]]):format(table_num, w_id, d_id, c_id)) 513 | 514 | -- c_balance, c_first, c_middle, c_last = 515 | -- con:query_row(([[SELECT c_balance, c_first, c_middle, c_last 516 | -- FROM customer%d 517 | -- WHERE c_w_id = %d 518 | -- AND c_d_id=%d 519 | -- AND c_id=%d]]) 520 | -- :format(table_num, w_id, d_id, c_id )) 521 | 522 | end 523 | --[=[ Initial query 524 | SELECT o_id, o_entry_d, COALESCE(o_carrier_id,0) FROM orders 525 | WHERE o_w_id = ? AND o_d_id = ? AND o_c_id = ? AND o_id = 526 | (SELECT MAX(o_id) FROM orders WHERE o_w_id = ? AND o_d_id = ? AND o_c_id = ?) 527 | 528 | rs = con:query(([[SELECT o_id, o_entry_d, COALESCE(o_carrier_id,0) 529 | FROM orders%d WHERE o_w_id = %d AND o_d_id = %d AND o_c_id = %d AND o_id = 530 | (SELECT MAX(o_id) FROM orders%d WHERE o_w_id = %d AND o_d_id = %d AND o_c_id = %d)]]) 531 | :format(table_num, w_id, d_id, c_id, table_num, w_id, d_id, c_id)) 532 | --]=] 533 | 534 | --[[ Query from tpcc standard 535 | 536 | EXEC SQL SELECT o_id, o_carrier_id, o_entry_d 537 | INTO :o_id, :o_carrier_id, :entdate 538 | FROM orders 539 | ORDER BY o_id DESC; 540 | -]] 541 | local o_id 542 | 543 | o_id = con:query_row(([[execute p_orderstatus4_%d(%d,%d,%d)]]):format(table_num, w_id, d_id, c_id)) 544 | -- o_id = con:query_row(([[SELECT o_id, o_carrier_id, o_entry_d 545 | -- FROM orders%d 546 | -- WHERE o_w_id = %d 547 | -- AND o_d_id = %d 548 | -- AND o_c_id = %d 549 | -- ORDER BY o_id DESC]]): 550 | -- format(table_num, w_id, d_id, c_id)) 551 | 552 | 553 | -- rs = con:query(([[SELECT o_id, o_carrier_id, o_entry_d 554 | -- FROM orders%d 555 | -- WHERE o_w_id = %d 556 | -- AND o_d_id = %d 557 | -- AND o_c_id = %d 558 | -- ORDER BY o_id DESC]]): 559 | -- format(table_num, w_id, d_id, c_id)) 560 | -- if rs.nrows == 0 then 561 | -- print(string.format("Error o_id %d, %d, %d, %d\n", table_num , w_id , d_id , c_id)) 562 | -- end 563 | -- for i = 1, rs.nrows do 564 | -- row = rs:fetch_row() 565 | -- o_id= row[1] 566 | -- end 567 | 568 | -- SELECT ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, 569 | -- ol_delivery_d 570 | -- FROM order_line 571 | -- WHERE ol_w_id = :c_w_id 572 | -- AND ol_d_id = :c_d_id 573 | -- AND ol_o_id = :o_id;*/ 574 | 575 | rs = con:query(([[execute p_orderstatus5_%d(%d,%d,%d)]]):format(table_num, w_id, d_id, o_id)) 576 | -- rs = con:query(([[SELECT ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_delivery_d 577 | -- FROM order_line%d WHERE ol_w_id = %d AND ol_d_id = %d AND ol_o_id = %d]]) 578 | -- :format(table_num, w_id, d_id, d_id, o_id)) 579 | 580 | for i = 1, rs.nrows do 581 | row = rs:fetch_row() 582 | local ol_i_id = row[1] 583 | local ol_supply_w_id = row[2] 584 | local ol_quantity = row[3] 585 | local ol_amount = row[4] 586 | local ol_delivery_d = row[5] 587 | end 588 | con:query("COMMIT") 589 | 590 | end 591 | 592 | function delivery() 593 | local table_num = sysbench.rand.uniform(1, sysbench.opt.tables) 594 | local w_id = sysbench.rand.uniform(1, sysbench.opt.scale) 595 | local o_carrier_id = sysbench.rand.uniform(1, 10) 596 | 597 | con:query("BEGIN") 598 | for d_id = 1, DIST_PER_WARE do 599 | 600 | -- SELECT COALESCE(MIN(no_o_id),0) INTO :no_o_id 601 | -- FROM new_orders 602 | -- WHERE no_d_id = :d_id AND no_w_id = :w_id;*/ 603 | 604 | -- rs = con:query(([[SELECT COALESCE(MIN(no_o_id),0) no_o_id 605 | -- FROM new_orders%d WHERE no_d_id = %d AND no_w_id = %d FOR UPDATE]]) 606 | -- :format(table_num, d_id, w_id)) 607 | 608 | local no_o_id 609 | 610 | rs = con:query(([[execute p_delivery1_%d(%d,%d)]]):format(table_num, d_id, w_id)) 611 | -- rs = con:query(([[SELECT no_o_id 612 | -- FROM new_orders%d 613 | -- WHERE no_d_id = %d 614 | -- AND no_w_id = %d 615 | -- ORDER BY no_o_id ASC LIMIT 1 FOR UPDATE]]) 616 | -- :format(table_num, d_id, w_id)) 617 | 618 | if (rs.nrows > 0) then 619 | no_o_id=unpack(rs:fetch_row(), 1, rs.nfields) 620 | end 621 | 622 | if (no_o_id ~= nil ) then 623 | 624 | -- DELETE FROM new_orders WHERE no_o_id = :no_o_id AND no_d_id = :d_id 625 | -- AND no_w_id = :w_id;*/ 626 | 627 | con:query(([[execute p_delivery2_%d(%d,%d,%d)]]):format(table_num, no_o_id, d_id, w_id)) 628 | -- con:query(([[DELETE FROM new_orders%d 629 | -- WHERE no_o_id = %d 630 | -- AND no_d_id = %d 631 | -- AND no_w_id = %d]]) 632 | -- :format(table_num, no_o_id, d_id, w_id)) 633 | 634 | -- SELECT o_c_id INTO :c_id FROM orders 635 | -- WHERE o_id = :no_o_id AND o_d_id = :d_id 636 | -- AND o_w_id = :w_id;*/ 637 | 638 | local o_c_id 639 | o_c_id = con:query_row(([[execute p_delivery3_%d(%d,%d,%d)]]):format(table_num, no_o_id, d_id, w_id)) 640 | -- o_c_id = con:query_row(([[SELECT o_c_id 641 | -- FROM orders%d 642 | -- WHERE o_id = %d 643 | -- AND o_d_id = %d 644 | -- AND o_w_id = %d]]) 645 | -- :format(table_num, no_o_id, d_id, w_id)) 646 | 647 | -- UPDATE orders SET o_carrier_id = :o_carrier_id 648 | -- WHERE o_id = :no_o_id AND o_d_id = :d_id AND 649 | -- o_w_id = :w_id;*/ 650 | 651 | con:query(([[execute p_delivery4_%d(%d,%d,%d,%d)]]):format(table_num, o_carrier_id, no_o_id, d_id, w_id)) 652 | -- con:query(([[UPDATE orders%d 653 | -- SET o_carrier_id = %d 654 | -- WHERE o_id = %d 655 | -- AND o_d_id = %d 656 | -- AND o_w_id = %d]]) 657 | -- :format(table_num, o_carrier_id, no_o_id, d_id, w_id)) 658 | 659 | -- UPDATE order_line 660 | -- SET ol_delivery_d = :datetime 661 | -- WHERE ol_o_id = :no_o_id AND ol_d_id = :d_id AND 662 | -- ol_w_id = :w_id;*/ 663 | 664 | con:query(([[execute p_delivery5_%d(%d,%d,%d)]]):format(table_num, no_o_id, d_id, w_id)) 665 | -- con:query(([[UPDATE order_line%d 666 | -- SET ol_delivery_d = NOW() 667 | -- WHERE ol_o_id = %d 668 | -- AND ol_d_id = %d 669 | -- AND ol_w_id = %d]]) 670 | -- :format(table_num, no_o_id, d_id, w_id)) 671 | 672 | 673 | -- SELECT SUM(ol_amount) INTO :ol_total 674 | -- FROM order_line 675 | -- WHERE ol_o_id = :no_o_id AND ol_d_id = :d_id 676 | -- AND ol_w_id = :w_id;*/ 677 | 678 | local sm_ol_amount 679 | sm_ol_amount = con:query_row(([[execute p_delivery6_%d(%d,%d,%d)]]):format(table_num, no_o_id, d_id, w_id)) 680 | -- sm_ol_amount = con:query_row(([[SELECT SUM(ol_amount) sm 681 | -- FROM order_line%d 682 | -- WHERE ol_o_id = %d 683 | -- AND ol_d_id = %d 684 | -- AND ol_w_id = %d]]) 685 | -- :format(table_num, no_o_id, d_id, w_id)) 686 | 687 | -- UPDATE customer SET c_balance = c_balance + :ol_total , 688 | -- c_delivery_cnt = c_delivery_cnt + 1 689 | -- WHERE c_id = :c_id AND c_d_id = :d_id AND 690 | -- c_w_id = :w_id;*/ 691 | -- print(string.format("update customer table %d, cid %d, did %d, wid %d balance %f",table_num, o_c_id, d_id, w_id, sm_ol_amount)) 692 | 693 | 694 | con:query(([[execute p_delivery7_%d(%d,%d,%d,%d)]]):format(table_num, sm_ol_amount, o_c_id, d_id, w_id)) 695 | -- con:query(([[UPDATE customer%d 696 | -- SET c_balance = c_balance + %f, 697 | -- c_delivery_cnt = c_delivery_cnt + 1 698 | -- WHERE c_id = %d 699 | -- AND c_d_id = %d 700 | -- AND c_w_id = %d]]) 701 | -- :format(table_num, sm_ol_amount, o_c_id, d_id, w_id)) 702 | end 703 | 704 | end 705 | con:query("COMMIT") 706 | 707 | end 708 | 709 | function stocklevel() 710 | local table_num = sysbench.rand.uniform(1, sysbench.opt.tables) 711 | local w_id = sysbench.rand.uniform(1, sysbench.opt.scale) 712 | local d_id = sysbench.rand.uniform(1, DIST_PER_WARE) 713 | local level = sysbench.rand.uniform(10, 20) 714 | 715 | con:query("BEGIN") 716 | 717 | -- /*EXEC_SQL SELECT d_next_o_id 718 | -- FROM district 719 | -- WHERE d_id = :d_id 720 | -- AND d_w_id = :w_id;*/ 721 | 722 | -- What variant of queries to use for stock_level transaction 723 | -- case1 - specification 724 | -- case2 - modified/simplified 725 | 726 | local stock_level_queries="case1" 727 | local d_next_o_id 728 | 729 | 730 | d_next_o_id = con:query_row(([[execute p_stocklevel1_%d(%d,%d)]]):format(table_num, d_id, w_id)) 731 | -- d_next_o_id = con:query_row(([[SELECT d_next_o_id 732 | -- FROM district%d 733 | -- WHERE d_id = %d AND d_w_id= %d]]) 734 | -- :format( table_num, d_id, w_id)) 735 | 736 | if stock_level_queries == "case1" then 737 | 738 | --[[ 739 | SELECT COUNT(DISTINCT (s_i_id)) INTO :stock_count 740 | FROM order_line, stock 741 | WHERE ol_w_id=:w_id AND ol_d_id=:d_id AND ol_o_id<:o_id AND ol_o_id>=:o_id-20 AND s_w_id=:w_id AND s_i_id=ol_i_id AND s_quantity < :threshold; 742 | --]] 743 | 744 | rs = con:query(([[execute p_stocklevel2_%d(%d,%d,%d,%d,%d,%d)]]):format(table_num, w_id, d_id, d_next_o_id, d_next_o_id - 20, w_id, level)) 745 | -- rs = con:query(([[SELECT COUNT(DISTINCT (s_i_id)) 746 | -- FROM order_line%d, stock%d 747 | -- WHERE ol_w_id = %d 748 | -- AND ol_d_id = %d 749 | -- AND ol_o_id < %d 750 | -- AND ol_o_id >= %d 751 | -- AND s_w_id= %d 752 | -- AND s_i_id=ol_i_id 753 | -- AND s_quantity < %d ]]) 754 | -- :format(table_num, table_num, w_id, d_id, d_next_o_id, d_next_o_id - 20, w_id, level )) 755 | 756 | 757 | 758 | -- SELECT DISTINCT ol_i_id 759 | -- FROM order_line 760 | -- WHERE ol_w_id = :w_id 761 | -- AND ol_d_id = :d_id 762 | -- AND ol_o_id < :d_next_o_id 763 | -- AND ol_o_id >= (:d_next_o_id - 20); 764 | 765 | 766 | else 767 | 768 | rs = con:query(([[execute p_stocklevel3_%d(%d,%d,%d,%d)]]):format(table_num, w_id, d_id, d_next_o_id, d_next_o_id - 20)) 769 | -- rs = con:query(([[SELECT DISTINCT ol_i_id FROM order_line%d 770 | -- WHERE ol_w_id = %d AND ol_d_id = %d 771 | -- AND ol_o_id < %d AND ol_o_id >= %d]]) 772 | -- :format(table_num, w_id, d_id, d_next_o_id, d_next_o_id - 20 )) 773 | 774 | local ol_i_id = {} 775 | 776 | for i = 1, rs.nrows do 777 | ol_i_id[i] = unpack(rs:fetch_row(), 1, rs.nfields) 778 | end 779 | for i = 1, #ol_i_id do 780 | -- SELECT count(*) INTO :i_count 781 | -- FROM stock 782 | -- WHERE s_w_id = :w_id 783 | -- AND s_i_id = :ol_i_id 784 | -- AND s_quantity < :level;*/ 785 | 786 | rs = con:query(([[execute p_stocklevel4_%d(%d,%d,%d)]]):format(table_num, w_id, ol_i_id, level)) 787 | -- rs = con:query(([[SELECT count(*) FROM stock%d 788 | -- WHERE s_w_id = %d AND s_i_id = %d 789 | -- AND s_quantity < %d]]) 790 | -- :format(table_num, w_id, ol_i_id[i], level ) ) 791 | 792 | local cnt 793 | for i = 1, rs.nrows do 794 | cnt = unpack(rs:fetch_row(), 1, rs.nfields) 795 | end 796 | 797 | end 798 | end 799 | 800 | con:query("COMMIT") 801 | 802 | end 803 | 804 | -- function purge to remove all orders, this is useful if we want to limit data directory in size 805 | 806 | function purge() 807 | -- for i = 1, 10 do 808 | -- local table_num = sysbench.rand.uniform(1, sysbench.opt.tables) 809 | for i = 1, sysbench.opt.tables do 810 | local table_num = i 811 | local w_id = sysbench.rand.uniform(1, sysbench.opt.scale) 812 | local d_id = sysbench.rand.uniform(1, DIST_PER_WARE) 813 | 814 | con:query("BEGIN") 815 | 816 | local m_o_id 817 | 818 | rs = con:query(([[execute p_purge1_%d(%d,%d)]]):format(table_num, w_id, d_id)) 819 | -- rs = con:query(([[SELECT min(no_o_id) mo 820 | -- FROM new_orders%d 821 | -- WHERE no_w_id = %d AND no_d_id = %d]]) 822 | -- :format(table_num, w_id, d_id)) 823 | 824 | if (rs.nrows > 0) then 825 | m_o_id=unpack(rs:fetch_row(), 1, rs.nfields) 826 | end 827 | 828 | if (m_o_id ~= nil ) then 829 | -- select o_id,o.o_d_id from orders2 o, (select o_c_id,o_w_id,o_d_id,count(distinct o_id) from orders2 where o_w_id=1 and o_id > 2100 and o_id < 11153 group by o_c_id,o_d_id,o_w_id having count( distinct o_id) > 1 limit 1) t where t.o_w_id=o.o_w_id and t.o_d_id=o.o_d_id and t.o_c_id=o.o_c_id limit 1; 830 | 831 | 832 | -- find an order to delete 833 | rs = con:query(([[execute p_purge2_%d(%d,%d,%d)]]):format(table_num, w_id, d_id, m_o_id)) 834 | -- rs = con:query(([[SELECT o_id FROM orders%d o, (SELECT o_c_id,o_w_id,o_d_id,count(distinct o_id) FROM orders%d WHERE o_w_id=%d AND o_d_id=%d AND o_id > 2100 AND o_id < %d GROUP BY o_c_id,o_d_id,o_w_id having count( distinct o_id) > 1 limit 1) t WHERE t.o_w_id=o.o_w_id and t.o_d_id=o.o_d_id and t.o_c_id=o.o_c_id limit 1 ]]) 835 | -- :format(table_num, table_num, w_id, d_id, m_o_id)) 836 | 837 | local del_o_id 838 | if (rs.nrows > 0) then 839 | del_o_id=unpack(rs:fetch_row(), 1, rs.nfields) 840 | end 841 | 842 | if (del_o_id ~= nil ) then 843 | 844 | con:query(([[execute p_purge3_%d(%d,%d,%d)]]):format(table_num, w_id, d_id, del_o_id)) 845 | con:query(([[execute p_purge4_%d(%d,%d,%d)]]):format(table_num, w_id, d_id, del_o_id)) 846 | con:query(([[execute p_purge5_%d(%d,%d)]]):format(table_num, w_id, d_id)) 847 | 848 | -- con:query(([[DELETE FROM order_line%d where ol_w_id=%d AND ol_d_id=%d AND ol_o_id=%d]]) 849 | -- :format(table_num, w_id, d_id, del_o_id)) 850 | -- con:query(([[DELETE FROM orders%d where o_w_id=%d AND o_d_id=%d and o_id=%d]]) 851 | -- :format(table_num, w_id, d_id, del_o_id)) 852 | -- con:query(([[DELETE FROM history%d where h_w_id=%d AND h_d_id=%d LIMIT 10]]) 853 | -- :format(table_num, w_id, d_id )) 854 | 855 | end 856 | 857 | end 858 | 859 | con:query("COMMIT") 860 | end 861 | end 862 | 863 | -- vim:ts=4 ss=4 sw=4 expandtab 864 | -------------------------------------------------------------------------------- /tpcc_run.lua.old: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sysbench 2 | 3 | -- This program is free software; you can redistribute it and/or modify 4 | -- it under the terms of the GNU General Public License as published by 5 | -- the Free Software Foundation; either version 2 of the License, or 6 | -- (at your option) any later version. 7 | 8 | -- This program is distributed in the hope that it will be useful, 9 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | -- GNU General Public License for more details. 12 | 13 | -- You should have received a copy of the GNU General Public License 14 | -- along with this program; if not, write to the Free Software 15 | -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 16 | 17 | -- ---------------------------------------------------------------------- 18 | -- TPCC-like workload 19 | -- ---------------------------------------------------------------------- 20 | 21 | require("tpcc_common") 22 | 23 | 24 | -- 25 | -- produce the id of a valid warehouse other than home_ware 26 | -- (assuming there is one) 27 | -- 28 | function other_ware (home_ware) 29 | local tmp 30 | 31 | if sysbench.opt.scale == 1 then return home_ware end 32 | repeat 33 | tmp = sysbench.rand.uniform(1, sysbench.opt.scale) 34 | until tmp == home_ware 35 | return tmp 36 | end 37 | 38 | function new_order() 39 | 40 | -- prep work 41 | 42 | local table_num = sysbench.rand.uniform(1, sysbench.opt.tables) 43 | local w_id = sysbench.rand.uniform(1, sysbench.opt.scale) 44 | local d_id = sysbench.rand.uniform(1, DIST_PER_WARE) 45 | local c_id = NURand(1023, 1, CUST_PER_DIST) 46 | 47 | local ol_cnt = sysbench.rand.uniform(5, 15); 48 | local rbk = sysbench.rand.uniform(1, 100); 49 | local itemid = {} 50 | local supware = {} 51 | local qty = {} 52 | local all_local = 1 53 | 54 | for i = 1, ol_cnt 55 | do 56 | itemid[i] = NURand(8191, 1, MAXITEMS) 57 | if ((i == ol_cnt - 1) and (rbk == 1)) 58 | then 59 | itemid[i] = -1 60 | end 61 | if sysbench.rand.uniform(1, 100) ~= 1 62 | then 63 | supware[i] = w_id 64 | else 65 | supware[i] = other_ware(w_id) 66 | all_local = 0 67 | end 68 | qty[i] = sysbench.rand.uniform(1, 10) 69 | end 70 | 71 | 72 | -- SELECT c_discount, c_last, c_credit, w_tax 73 | -- INTO :c_discount, :c_last, :c_credit, :w_tax 74 | -- FROM customer, warehouse 75 | -- WHERE w_id = :w_id 76 | -- AND c_w_id = w_id 77 | -- AND c_d_id = :d_id 78 | -- AND c_id = :c_id; 79 | 80 | con:query("BEGIN") 81 | 82 | local c_discount 83 | local c_last 84 | local c_credit 85 | local w_tax 86 | 87 | c_discount, c_last, c_credit, w_tax = con:query_row(([[SELECT c_discount, c_last, c_credit, w_tax 88 | FROM customer%d, warehouse%d 89 | WHERE w_id = %d 90 | AND c_w_id = w_id 91 | AND c_d_id = %d 92 | AND c_id = %d]]): 93 | format(table_num, table_num, w_id, d_id, c_id)) 94 | 95 | -- SELECT d_next_o_id, d_tax INTO :d_next_o_id, :d_tax 96 | -- FROM district 97 | -- WHERE d_id = :d_id 98 | -- AND d_w_id = :w_id 99 | -- FOR UPDATE 100 | local d_next_o_id 101 | local d_tax 102 | 103 | d_next_o_id, d_tax = con:query_row(([[SELECT d_next_o_id, d_tax 104 | FROM district%d 105 | WHERE d_w_id = %d 106 | AND d_id = %d FOR UPDATE]]): 107 | format(table_num, w_id, d_id)) 108 | 109 | -- UPDATE district SET d_next_o_id = :d_next_o_id + 1 110 | -- WHERE d_id = :d_id 111 | -- AND d_w_id = :w_id; 112 | 113 | con:query(([[UPDATE district%d 114 | SET d_next_o_id = %d 115 | WHERE d_id = %d AND d_w_id= %d]]):format(table_num, d_next_o_id + 1, d_id, w_id)) 116 | 117 | --INSERT INTO orders (o_id, o_d_id, o_w_id, o_c_id, 118 | -- o_entry_d, o_ol_cnt, o_all_local) 119 | -- VALUES(:o_id, :d_id, :w_id, :c_id, 120 | -- :datetime, 121 | -- :o_ol_cnt, :o_all_local); 122 | 123 | con:query(([[INSERT INTO orders%d 124 | (o_id, o_d_id, o_w_id, o_c_id, o_entry_d, o_ol_cnt, o_all_local) 125 | VALUES (%d,%d,%d,%d,NOW(),%d,%d)]]): 126 | format(table_num, d_next_o_id, d_id, w_id, c_id, ol_cnt, all_local)) 127 | 128 | -- INSERT INTO new_orders (no_o_id, no_d_id, no_w_id) 129 | -- VALUES (:o_id,:d_id,:w_id); */ 130 | 131 | con:query(([[INSERT INTO new_orders%d (no_o_id, no_d_id, no_w_id) 132 | VALUES (%d,%d,%d)]]): 133 | format(table_num, d_next_o_id, d_id, w_id)) 134 | 135 | for ol_number=1, ol_cnt do 136 | local ol_supply_w_id = supware[ol_number] 137 | local ol_i_id = itemid[ol_number] 138 | local ol_quantity = qty[ol_number] 139 | 140 | -- SELECT i_price, i_name, i_data 141 | -- INTO :i_price, :i_name, :i_data 142 | -- FROM item 143 | -- WHERE i_id = :ol_i_id;*/ 144 | 145 | rs = con:query(([[SELECT i_price, i_name, i_data 146 | FROM item%d 147 | WHERE i_id = %d]]): 148 | format(table_num, ol_i_id)) 149 | 150 | local i_price 151 | local i_name 152 | local i_data 153 | 154 | if rs.nrows == 0 then 155 | -- print("ROLLBACK") 156 | ffi.C.sb_counter_inc(sysbench.tid, ffi.C.SB_CNT_ERROR) 157 | con:query("ROLLBACK") 158 | return 159 | end 160 | 161 | i_price, i_name, i_data = unpack(rs:fetch_row(), 1, rs.nfields) 162 | 163 | -- SELECT s_quantity, s_data, s_dist_01, s_dist_02, 164 | -- s_dist_03, s_dist_04, s_dist_05, s_dist_06, 165 | -- s_dist_07, s_dist_08, s_dist_09, s_dist_10 166 | -- INTO :s_quantity, :s_data, :s_dist_01, :s_dist_02, 167 | -- :s_dist_03, :s_dist_04, :s_dist_05, :s_dist_06, 168 | -- :s_dist_07, :s_dist_08, :s_dist_09, :s_dist_10 169 | -- FROM stock 170 | -- WHERE s_i_id = :ol_i_id 171 | -- AND s_w_id = :ol_supply_w_id 172 | -- FOR UPDATE;*/ 173 | 174 | local s_quantity 175 | local s_data 176 | local ol_dist_info 177 | 178 | s_quantity, s_data, ol_dist_info = con:query_row(([[SELECT s_quantity, s_data, s_dist_%s s_dist 179 | FROM stock%d 180 | WHERE s_i_id = %d AND s_w_id= %d FOR UPDATE]]): 181 | format(string.format("%02d",d_id),table_num,ol_i_id,ol_supply_w_id )) 182 | 183 | s_quantity=tonumber(s_quantity) 184 | if (s_quantity > ol_quantity) then 185 | s_quantity = s_quantity - ol_quantity 186 | else 187 | s_quantity = s_quantity - ol_quantity + 91 188 | end 189 | 190 | -- UPDATE stock SET s_quantity = :s_quantity 191 | -- WHERE s_i_id = :ol_i_id 192 | -- AND s_w_id = :ol_supply_w_id;*/ 193 | 194 | con:query(([[UPDATE stock%d 195 | SET s_quantity = %d 196 | WHERE s_i_id = %d 197 | AND s_w_id= %d]]): 198 | format(table_num, s_quantity, ol_i_id, ol_supply_w_id)) 199 | 200 | i_price=tonumber(i_price) 201 | w_tax=tonumber(w_tax) 202 | d_tax=tonumber(d_tax) 203 | c_discount=tonumber(c_discount) 204 | 205 | ol_amount = ol_quantity * i_price * (1 + w_tax + d_tax) * (1 - c_discount); 206 | 207 | -- INSERT INTO order_line (ol_o_id, ol_d_id, ol_w_id, 208 | -- ol_number, ol_i_id, 209 | -- ol_supply_w_id, ol_quantity, 210 | -- ol_amount, ol_dist_info) 211 | -- VALUES (:o_id, :d_id, :w_id, :ol_number, :ol_i_id, 212 | -- :ol_supply_w_id, :ol_quantity, :ol_amount, 213 | -- :ol_dist_info); 214 | 215 | con:query(([[INSERT INTO order_line%d 216 | (ol_o_id, ol_d_id, ol_w_id, ol_number, ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_dist_info) 217 | VALUES (%d,%d,%d,%d,%d,%d,%d,%d,'%s')]]): 218 | format(table_num, d_next_o_id, d_id, w_id, ol_number, ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_dist_info)) 219 | 220 | end 221 | 222 | con:query("COMMIT") 223 | 224 | end 225 | 226 | function payment() 227 | -- prep work 228 | 229 | local table_num = sysbench.rand.uniform(1, sysbench.opt.tables) 230 | local w_id = sysbench.rand.uniform(1, sysbench.opt.scale) 231 | local d_id = sysbench.rand.uniform(1, DIST_PER_WARE) 232 | local c_id = NURand(1023, 1, CUST_PER_DIST) 233 | local h_amount = sysbench.rand.uniform(1,5000) 234 | local byname 235 | local c_w_id 236 | local c_d_id 237 | local c_last = Lastname(NURand(255,0,999)) 238 | 239 | if sysbench.rand.uniform(1, 100) <= 60 then 240 | byname = 1 -- select by last name 241 | else 242 | byname = 0 -- select by customer id 243 | end 244 | 245 | if sysbench.rand.uniform(1, 100) <= 85 then 246 | c_w_id = w_id 247 | c_d_id = d_id 248 | else 249 | c_w_id = other_ware(w_id) 250 | c_d_id = sysbench.rand.uniform(1, DIST_PER_WARE) 251 | end 252 | 253 | -- UPDATE warehouse SET w_ytd = w_ytd + :h_amount 254 | -- WHERE w_id =:w_id 255 | 256 | con:query("BEGIN") 257 | 258 | con:query(([[UPDATE warehouse%d 259 | SET w_ytd = w_ytd + %d 260 | WHERE w_id = %d]]):format(table_num, h_amount, w_id )) 261 | 262 | -- SELECT w_street_1, w_street_2, w_city, w_state, w_zip, 263 | -- w_name 264 | -- INTO :w_street_1, :w_street_2, :w_city, :w_state, 265 | -- :w_zip, :w_name 266 | -- FROM warehouse 267 | -- WHERE w_id = :w_id;*/ 268 | local w_street_1, w_street_2, w_city, w_state, w_zip, w_name 269 | 270 | w_street_1, w_street_2, w_city, w_state, w_zip, w_name = 271 | con:query_row(([[SELECT w_street_1, w_street_2, w_city, w_state, w_zip, w_name 272 | FROM warehouse%d 273 | WHERE w_id = %d]]):format(table_num, w_id)) 274 | 275 | -- UPDATE district SET d_ytd = d_ytd + :h_amount 276 | -- WHERE d_w_id = :w_id 277 | -- AND d_id = :d_id;*/ 278 | 279 | con:query(([[UPDATE district%d 280 | SET d_ytd = d_ytd + %d 281 | WHERE d_w_id = %d 282 | AND d_id= %d]]):format(table_num, h_amount, w_id, d_id)) 283 | 284 | 285 | local d_street_1,d_street_2, d_city, d_state, d_zip, d_name 286 | 287 | d_street_1,d_street_2, d_city, d_state, d_zip, d_name = 288 | con:query_row(([[SELECT d_street_1, d_street_2, d_city, d_state, d_zip, d_name 289 | FROM district%d 290 | WHERE d_w_id = %d 291 | AND d_id = %d]]):format(table_num, w_id, d_id )) 292 | 293 | if byname == 1 then 294 | 295 | -- SELECT count(c_id) 296 | -- FROM customer 297 | -- WHERE c_w_id = :c_w_id 298 | -- AND c_d_id = :c_d_id 299 | -- AND c_last = :c_last;*/ 300 | 301 | local namecnt = con:query_row(([[SELECT count(c_id) namecnt 302 | FROM customer%d 303 | WHERE c_w_id = %d 304 | AND c_d_id= %d 305 | AND c_last='%s']]):format(table_num, w_id, c_d_id, c_last )) 306 | -- SELECT c_id 307 | -- FROM customer 308 | -- WHERE c_w_id = :c_w_id 309 | -- AND c_d_id = :c_d_id 310 | -- AND c_last = :c_last 311 | -- ORDER BY c_first; 312 | 313 | if namecnt % 2 == 0 then 314 | namecnt = namecnt + 1 315 | end 316 | 317 | rs = con:query(([[SELECT c_id 318 | FROM customer%d 319 | WHERE c_w_id = %d AND c_d_id= %d 320 | AND c_last='%s' ORDER BY c_first]] 321 | ):format(table_num, w_id, c_d_id, c_last )) 322 | 323 | for i = 1, (namecnt / 2 ) + 1 do 324 | row = rs:fetch_row() 325 | c_id = row[1] 326 | end 327 | end -- byname 328 | 329 | -- SELECT c_first, c_middle, c_last, c_street_1, 330 | -- c_street_2, c_city, c_state, c_zip, c_phone, 331 | -- c_credit, c_credit_lim, c_discount, c_balance, 332 | -- c_since 333 | -- FROM customer 334 | -- WHERE c_w_id = :c_w_id 335 | -- AND c_d_id = :c_d_id 336 | -- AND c_id = :c_id 337 | -- FOR UPDATE; 338 | 339 | local c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, 340 | c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_since 341 | 342 | c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, 343 | c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_since = 344 | con:query_row(([[SELECT c_first, c_middle, c_last, c_street_1, 345 | c_street_2, c_city, c_state, c_zip, c_phone, 346 | c_credit, c_credit_lim, c_discount, c_balance, c_ytd_payment, c_since 347 | FROM customer%d 348 | WHERE c_w_id = %d 349 | AND c_d_id= %d 350 | AND c_id=%d FOR UPDATE]]) 351 | :format(table_num, w_id, c_d_id, c_id )) 352 | 353 | c_balance = tonumber(c_balance) - h_amount 354 | c_ytd_payment = tonumber(c_ytd_payment) + h_amount 355 | 356 | if c_credit == "BC" then 357 | -- SELECT c_data 358 | -- INTO :c_data 359 | -- FROM customer 360 | -- WHERE c_w_id = :c_w_id 361 | -- AND c_d_id = :c_d_id 362 | -- AND c_id = :c_id; */ 363 | 364 | local c_data 365 | c_data = con:query_row(([[SELECT c_data 366 | FROM customer%d 367 | WHERE c_w_id = %d 368 | AND c_d_id=%d 369 | AND c_id= %d]]): 370 | format(table_num, w_id, c_d_id, c_id )) 371 | 372 | local c_new_data=string.sub(string.format("| %4d %2d %4d %2d %4d $%7.2f %12s %24s", 373 | c_id, c_d_id, c_w_id, d_id, w_id, h_amount, os.time(), c_data), 1, 500); 374 | 375 | -- UPDATE customer 376 | -- SET c_balance = :c_balance, c_data = :c_new_data 377 | -- WHERE c_w_id = :c_w_id 378 | -- AND c_d_id = :c_d_id 379 | -- AND c_id = :c_id 380 | con:query(([[UPDATE customer%d 381 | SET c_balance=%f, c_ytd_payment=%f, c_data='%s' 382 | WHERE c_w_id = %d 383 | AND c_d_id=%d 384 | AND c_id=%d]]) 385 | :format(table_num, c_balance, c_ytd_payment, c_new_data, w_id, c_d_id, c_id )) 386 | else 387 | con:query(([[UPDATE customer%d 388 | SET c_balance=%f, c_ytd_payment=%f 389 | WHERE c_w_id = %d 390 | AND c_d_id=%d 391 | AND c_id=%d]]) 392 | :format(table_num, c_balance, c_ytd_payment, w_id, c_d_id, c_id )) 393 | 394 | end 395 | 396 | -- INSERT INTO history(h_c_d_id, h_c_w_id, h_c_id, h_d_id, 397 | -- h_w_id, h_date, h_amount, h_data) 398 | -- VALUES(:c_d_id, :c_w_id, :c_id, :d_id, 399 | -- :w_id, 400 | -- :datetime, 401 | -- :h_amount, :h_data);*/ 402 | 403 | con:query(([[INSERT INTO history%d 404 | (h_c_d_id, h_c_w_id, h_c_id, h_d_id, h_w_id, h_date, h_amount, h_data) 405 | VALUES (%d,%d,%d,%d,%d,NOW(),%d,'%s')]]) 406 | :format(table_num, c_d_id, c_w_id, c_id, d_id, w_id, h_amount, string.format("%10s %10s ",w_name,d_name))) 407 | 408 | con:query("COMMIT") 409 | 410 | end 411 | 412 | function orderstatus() 413 | 414 | local table_num = sysbench.rand.uniform(1, sysbench.opt.tables) 415 | local w_id = sysbench.rand.uniform(1, sysbench.opt.scale) 416 | local d_id = sysbench.rand.uniform(1, DIST_PER_WARE) 417 | local c_id = NURand(1023, 1, CUST_PER_DIST) 418 | local byname 419 | local c_last = Lastname(NURand(255,0,999)) 420 | 421 | if sysbench.rand.uniform(1, 100) <= 60 then 422 | byname = 1 -- select by last name 423 | else 424 | byname = 0 -- select by customer id 425 | end 426 | 427 | local c_balance 428 | local c_first 429 | local c_middle 430 | con:query("BEGIN") 431 | 432 | if byname == 1 then 433 | -- /*EXEC_SQL SELECT count(c_id) 434 | -- FROM customer 435 | -- WHERE c_w_id = :c_w_id 436 | -- AND c_d_id = :c_d_id 437 | -- AND c_last = :c_last;*/ 438 | 439 | local namecnt 440 | namecnt = con:query_row(([[SELECT count(c_id) namecnt 441 | FROM customer%d 442 | WHERE c_w_id = %d 443 | AND c_d_id= %d 444 | AND c_last='%s']]): 445 | format(table_num, w_id, d_id, c_last )) 446 | 447 | -- SELECT c_balance, c_first, c_middle, c_id 448 | -- FROM customer 449 | -- WHERE c_w_id = :c_w_id 450 | -- AND c_d_id = :c_d_id 451 | -- AND c_last = :c_last 452 | -- ORDER BY c_first; 453 | 454 | rs = con:query(([[SELECT c_balance, c_first, c_middle, c_id 455 | FROM customer%d 456 | WHERE c_w_id = %d 457 | AND c_d_id= %d 458 | AND c_last='%s' ORDER BY c_first]]) 459 | :format(table_num, w_id, d_id, c_last )) 460 | 461 | if namecnt % 2 == 0 then 462 | namecnt = namecnt + 1 463 | end 464 | for i = 1, (namecnt / 2 ) + 1 do 465 | row = rs:fetch_row() 466 | c_balance = row[1] 467 | c_first = row[2] 468 | c_middle = row[3] 469 | c_id = row[4] 470 | end 471 | else 472 | -- SELECT c_balance, c_first, c_middle, c_last 473 | -- FROM customer 474 | -- WHERE c_w_id = :c_w_id 475 | -- AND c_d_id = :c_d_id 476 | -- AND c_id = :c_id;*/ 477 | c_balance, c_first, c_middle, c_last = 478 | con:query_row(([[SELECT c_balance, c_first, c_middle, c_last 479 | FROM customer%d 480 | WHERE c_w_id = %d 481 | AND c_d_id=%d 482 | AND c_id=%d]]) 483 | :format(table_num, w_id, d_id, c_id )) 484 | end 485 | --[=[ Initial query 486 | SELECT o_id, o_entry_d, COALESCE(o_carrier_id,0) FROM orders 487 | WHERE o_w_id = ? AND o_d_id = ? AND o_c_id = ? AND o_id = 488 | (SELECT MAX(o_id) FROM orders WHERE o_w_id = ? AND o_d_id = ? AND o_c_id = ?) 489 | 490 | rs = con:query(([[SELECT o_id, o_entry_d, COALESCE(o_carrier_id,0) 491 | FROM orders%d WHERE o_w_id = %d AND o_d_id = %d AND o_c_id = %d AND o_id = 492 | (SELECT MAX(o_id) FROM orders%d WHERE o_w_id = %d AND o_d_id = %d AND o_c_id = %d)]]) 493 | :format(table_num, w_id, d_id, c_id, table_num, w_id, d_id, c_id)) 494 | --]=] 495 | 496 | --[[ Query from tpcc standard 497 | 498 | EXEC SQL SELECT o_id, o_carrier_id, o_entry_d 499 | INTO :o_id, :o_carrier_id, :entdate 500 | FROM orders 501 | ORDER BY o_id DESC; 502 | -]] 503 | local o_id 504 | 505 | o_id = con:query_row(([[SELECT o_id, o_carrier_id, o_entry_d 506 | FROM orders%d 507 | WHERE o_w_id = %d 508 | AND o_d_id = %d 509 | AND o_c_id = %d 510 | ORDER BY o_id DESC]]): 511 | format(table_num, w_id, d_id, c_id)) 512 | 513 | -- rs = con:query(([[SELECT o_id, o_carrier_id, o_entry_d 514 | -- FROM orders%d 515 | -- WHERE o_w_id = %d 516 | -- AND o_d_id = %d 517 | -- AND o_c_id = %d 518 | -- ORDER BY o_id DESC]]): 519 | -- format(table_num, w_id, d_id, c_id)) 520 | -- if rs.nrows == 0 then 521 | -- print(string.format("Error o_id %d, %d, %d, %d\n", table_num , w_id , d_id , c_id)) 522 | -- end 523 | -- for i = 1, rs.nrows do 524 | -- row = rs:fetch_row() 525 | -- o_id= row[1] 526 | -- end 527 | 528 | -- SELECT ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, 529 | -- ol_delivery_d 530 | -- FROM order_line 531 | -- WHERE ol_w_id = :c_w_id 532 | -- AND ol_d_id = :c_d_id 533 | -- AND ol_o_id = :o_id;*/ 534 | 535 | rs = con:query(([[SELECT ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_delivery_d 536 | FROM order_line%d WHERE ol_w_id = %d AND ol_d_id = %d AND ol_o_id = %d]]) 537 | :format(table_num, w_id, d_id, d_id, o_id)) 538 | for i = 1, rs.nrows do 539 | row = rs:fetch_row() 540 | local ol_i_id = row[1] 541 | local ol_supply_w_id = row[2] 542 | local ol_quantity = row[3] 543 | local ol_amount = row[4] 544 | local ol_delivery_d = row[5] 545 | end 546 | con:query("COMMIT") 547 | 548 | end 549 | 550 | function delivery() 551 | local table_num = sysbench.rand.uniform(1, sysbench.opt.tables) 552 | local w_id = sysbench.rand.uniform(1, sysbench.opt.scale) 553 | local o_carrier_id = sysbench.rand.uniform(1, 10) 554 | 555 | con:query("BEGIN") 556 | for d_id = 1, DIST_PER_WARE do 557 | 558 | -- SELECT COALESCE(MIN(no_o_id),0) INTO :no_o_id 559 | -- FROM new_orders 560 | -- WHERE no_d_id = :d_id AND no_w_id = :w_id;*/ 561 | 562 | -- rs = con:query(([[SELECT COALESCE(MIN(no_o_id),0) no_o_id 563 | -- FROM new_orders%d WHERE no_d_id = %d AND no_w_id = %d FOR UPDATE]]) 564 | -- :format(table_num, d_id, w_id)) 565 | 566 | local no_o_id 567 | 568 | rs = con:query(([[SELECT no_o_id 569 | FROM new_orders%d 570 | WHERE no_d_id = %d 571 | AND no_w_id = %d 572 | ORDER BY no_o_id ASC LIMIT 1 FOR UPDATE]]) 573 | :format(table_num, d_id, w_id)) 574 | 575 | if (rs.nrows > 0) then 576 | no_o_id=unpack(rs:fetch_row(), 1, rs.nfields) 577 | end 578 | 579 | if (no_o_id ~= nil ) then 580 | 581 | -- DELETE FROM new_orders WHERE no_o_id = :no_o_id AND no_d_id = :d_id 582 | -- AND no_w_id = :w_id;*/ 583 | 584 | con:query(([[DELETE FROM new_orders%d 585 | WHERE no_o_id = %d 586 | AND no_d_id = %d 587 | AND no_w_id = %d]]) 588 | :format(table_num, no_o_id, d_id, w_id)) 589 | 590 | -- SELECT o_c_id INTO :c_id FROM orders 591 | -- WHERE o_id = :no_o_id AND o_d_id = :d_id 592 | -- AND o_w_id = :w_id;*/ 593 | 594 | local o_c_id 595 | o_c_id = con:query_row(([[SELECT o_c_id 596 | FROM orders%d 597 | WHERE o_id = %d 598 | AND o_d_id = %d 599 | AND o_w_id = %d]]) 600 | :format(table_num, no_o_id, d_id, w_id)) 601 | 602 | -- UPDATE orders SET o_carrier_id = :o_carrier_id 603 | -- WHERE o_id = :no_o_id AND o_d_id = :d_id AND 604 | -- o_w_id = :w_id;*/ 605 | 606 | con:query(([[UPDATE orders%d 607 | SET o_carrier_id = %d 608 | WHERE o_id = %d 609 | AND o_d_id = %d 610 | AND o_w_id = %d]]) 611 | :format(table_num, o_carrier_id, no_o_id, d_id, w_id)) 612 | 613 | -- UPDATE order_line 614 | -- SET ol_delivery_d = :datetime 615 | -- WHERE ol_o_id = :no_o_id AND ol_d_id = :d_id AND 616 | -- ol_w_id = :w_id;*/ 617 | con:query(([[UPDATE order_line%d 618 | SET ol_delivery_d = NOW() 619 | WHERE ol_o_id = %d 620 | AND ol_d_id = %d 621 | AND ol_w_id = %d]]) 622 | :format(table_num, no_o_id, d_id, w_id)) 623 | 624 | -- SELECT SUM(ol_amount) INTO :ol_total 625 | -- FROM order_line 626 | -- WHERE ol_o_id = :no_o_id AND ol_d_id = :d_id 627 | -- AND ol_w_id = :w_id;*/ 628 | 629 | local sm_ol_amount 630 | sm_ol_amount = con:query_row(([[SELECT SUM(ol_amount) sm 631 | FROM order_line%d 632 | WHERE ol_o_id = %d 633 | AND ol_d_id = %d 634 | AND ol_w_id = %d]]) 635 | :format(table_num, no_o_id, d_id, w_id)) 636 | 637 | -- UPDATE customer SET c_balance = c_balance + :ol_total , 638 | -- c_delivery_cnt = c_delivery_cnt + 1 639 | -- WHERE c_id = :c_id AND c_d_id = :d_id AND 640 | -- c_w_id = :w_id;*/ 641 | -- print(string.format("update customer table %d, cid %d, did %d, wid %d balance %f",table_num, o_c_id, d_id, w_id, sm_ol_amount)) 642 | con:query(([[UPDATE customer%d 643 | SET c_balance = c_balance + %f, 644 | c_delivery_cnt = c_delivery_cnt + 1 645 | WHERE c_id = %d 646 | AND c_d_id = %d 647 | AND c_w_id = %d]]) 648 | :format(table_num, sm_ol_amount, o_c_id, d_id, w_id)) 649 | end 650 | 651 | end 652 | con:query("COMMIT") 653 | 654 | end 655 | 656 | function stocklevel() 657 | local table_num = sysbench.rand.uniform(1, sysbench.opt.tables) 658 | local w_id = sysbench.rand.uniform(1, sysbench.opt.scale) 659 | local d_id = sysbench.rand.uniform(1, DIST_PER_WARE) 660 | local level = sysbench.rand.uniform(10, 20) 661 | 662 | con:query("BEGIN") 663 | 664 | -- /*EXEC_SQL SELECT d_next_o_id 665 | -- FROM district 666 | -- WHERE d_id = :d_id 667 | -- AND d_w_id = :w_id;*/ 668 | 669 | -- What variant of queries to use for stock_level transaction 670 | -- case1 - specification 671 | -- case2 - modified/simplified 672 | 673 | local stock_level_queries="case1" 674 | local d_next_o_id 675 | 676 | 677 | d_next_o_id = con:query_row(([[SELECT d_next_o_id 678 | FROM district%d 679 | WHERE d_id = %d AND d_w_id= %d]]) 680 | :format( table_num, d_id, w_id)) 681 | 682 | if stock_level_queries == "case1" then 683 | 684 | --[[ 685 | SELECT COUNT(DISTINCT (s_i_id)) INTO :stock_count 686 | FROM order_line, stock 687 | WHERE ol_w_id=:w_id AND ol_d_id=:d_id AND ol_o_id<:o_id AND ol_o_id>=:o_id-20 AND s_w_id=:w_id AND s_i_id=ol_i_id AND s_quantity < :threshold; 688 | --]] 689 | 690 | rs = con:query(([[SELECT COUNT(DISTINCT (s_i_id)) 691 | FROM order_line%d, stock%d 692 | WHERE ol_w_id = %d 693 | AND ol_d_id = %d 694 | AND ol_o_id < %d 695 | AND ol_o_id >= %d 696 | AND s_w_id= %d 697 | AND s_i_id=ol_i_id 698 | AND s_quantity < %d ]]) 699 | :format(table_num, table_num, w_id, d_id, d_next_o_id, d_next_o_id - 20, w_id, level )) 700 | 701 | 702 | 703 | -- SELECT DISTINCT ol_i_id 704 | -- FROM order_line 705 | -- WHERE ol_w_id = :w_id 706 | -- AND ol_d_id = :d_id 707 | -- AND ol_o_id < :d_next_o_id 708 | -- AND ol_o_id >= (:d_next_o_id - 20); 709 | 710 | 711 | else 712 | 713 | rs = con:query(([[SELECT DISTINCT ol_i_id FROM order_line%d 714 | WHERE ol_w_id = %d AND ol_d_id = %d 715 | AND ol_o_id < %d AND ol_o_id >= %d]]) 716 | :format(table_num, w_id, d_id, d_next_o_id, d_next_o_id - 20 )) 717 | 718 | local ol_i_id = {} 719 | 720 | for i = 1, rs.nrows do 721 | ol_i_id[i] = unpack(rs:fetch_row(), 1, rs.nfields) 722 | end 723 | for i = 1, #ol_i_id do 724 | 725 | 726 | -- SELECT count(*) INTO :i_count 727 | -- FROM stock 728 | -- WHERE s_w_id = :w_id 729 | -- AND s_i_id = :ol_i_id 730 | -- AND s_quantity < :level;*/ 731 | 732 | rs = con:query(([[SELECT count(*) FROM stock%d 733 | WHERE s_w_id = %d AND s_i_id = %d 734 | AND s_quantity < %d]]) 735 | :format(table_num, w_id, ol_i_id[i], level ) ) 736 | local cnt 737 | for i = 1, rs.nrows do 738 | cnt = unpack(rs:fetch_row(), 1, rs.nfields) 739 | end 740 | 741 | end 742 | end 743 | 744 | con:query("COMMIT") 745 | 746 | end 747 | 748 | -- function purge to remove all orders, this is useful if we want to limit data directory in size 749 | 750 | function purge() 751 | for i = 1, 10 do 752 | local table_num = sysbench.rand.uniform(1, sysbench.opt.tables) 753 | local w_id = sysbench.rand.uniform(1, sysbench.opt.scale) 754 | local d_id = sysbench.rand.uniform(1, DIST_PER_WARE) 755 | 756 | con:query("BEGIN") 757 | 758 | local m_o_id 759 | 760 | rs = con:query(([[SELECT min(no_o_id) mo 761 | FROM new_orders%d 762 | WHERE no_w_id = %d AND no_d_id = %d]]) 763 | :format(table_num, w_id, d_id)) 764 | 765 | if (rs.nrows > 0) then 766 | m_o_id=unpack(rs:fetch_row(), 1, rs.nfields) 767 | end 768 | 769 | if (m_o_id ~= nil ) then 770 | -- select o_id,o.o_d_id from orders2 o, (select o_c_id,o_w_id,o_d_id,count(distinct o_id) from orders2 where o_w_id=1 and o_id > 2100 and o_id < 11153 group by o_c_id,o_d_id,o_w_id having count( distinct o_id) > 1 limit 1) t where t.o_w_id=o.o_w_id and t.o_d_id=o.o_d_id and t.o_c_id=o.o_c_id limit 1; 771 | -- find an order to delete 772 | rs = con:query(([[SELECT o_id FROM orders%d o, (SELECT o_c_id,o_w_id,o_d_id,count(distinct o_id) FROM orders%d WHERE o_w_id=%d AND o_d_id=%d AND o_id > 2100 AND o_id < %d GROUP BY o_c_id,o_d_id,o_w_id having count( distinct o_id) > 1 limit 1) t WHERE t.o_w_id=o.o_w_id and t.o_d_id=o.o_d_id and t.o_c_id=o.o_c_id limit 1 ]]) 773 | :format(table_num, table_num, w_id, d_id, m_o_id)) 774 | 775 | local del_o_id 776 | if (rs.nrows > 0) then 777 | del_o_id=unpack(rs:fetch_row(), 1, rs.nfields) 778 | end 779 | 780 | if (del_o_id ~= nil ) then 781 | 782 | con:query(([[DELETE FROM order_line%d where ol_w_id=%d AND ol_d_id=%d AND ol_o_id=%d]]) 783 | :format(table_num, w_id, d_id, del_o_id)) 784 | con:query(([[DELETE FROM orders%d where o_w_id=%d AND o_d_id=%d and o_id=%d]]) 785 | :format(table_num, w_id, d_id, del_o_id)) 786 | con:query(([[DELETE FROM history%d where h_w_id=%d AND h_d_id=%d LIMIT 10]]) 787 | :format(table_num, w_id, d_id )) 788 | 789 | end 790 | 791 | end 792 | 793 | con:query("COMMIT") 794 | end 795 | end 796 | 797 | -- vim:ts=4 ss=4 sw=4 expandtab 798 | --------------------------------------------------------------------------------