ps:先轉了,周末在container上測試玩玩。。。
http://blog.csdn.net/signmem/article/details/17379427
特色
mysql/galera 是一種多主同步叢集,但隻限于使用 mysql/innodb 引擎,并具有下面特點
同步複制
多個主伺服器的拓撲結構
可以在任意節點上進行讀寫
自動控制成員,自動删除故障節點
自動加入節點
真正給予行級别的并發複制
排程客戶連接配接
優勢
參考下面基于 dbms 叢集的解決方法
不存在從伺服器角色
不存在事務丢失
讀寫操作可根據需要進行随意擴充
更少的闩操作
知識點
mysql/galera 叢集使用 galera 庫執行複制,對應 galera 複制接口,我們需要mysql 伺服器支援 wsrep api 接口
<a target="_blank" href="http://www.codership.com/products/mysql-write-set-replication-project">http://www.codership.com/products/mysql-write-set-replication-project</a>
是否可以使用 mysql 而不使用 mariadb?
不可以,因為 mysql 中沒有支援 wsrep_ 資料複制的參數,當然代碼級别上也具有很大差别
工作原理
mariadb 可以看做是常見的資料庫,負責連接配接應用(web, api 等)
單純的 mariadb 無法實作多個主伺服器資料同步
多台資料庫中資料同步由 wsrep 接口實作
最終目标,實作多個 mysql 同時讀寫
wsrep api
wsrep api 是一種資料庫插件接口,比較類似一種應用程式,主要針對寫複制
該程式主要用于定義應用程式如何調用複制庫實作回寫
wsrep api 由支援改庫的應用程式動态裝載
全局事務id(gtid)
wsrep api 描述下面複制模型,一個應用程式,如資料庫目前的一個對象,目前被用戶端修改,對象改變導緻事務産生一系列的原子性改變, 在叢集中所有的節點都具備相同的對象,并由同步複制應用都各自節點,按照相同的順序産生相同變化進而實作資料同步
到最後,wsrep api 将會配置設定一個全局事務id 該 id 具有下面功能
辨別對象的改變
辨別對象自身 id 最後狀态(正常情況下,id 是連續不中斷的)
gtid 包含
一個 uuid 作為對象辨別及經曆改變的序号,序号會發生連續的改變
gtid 允許比較應用程式狀态,建立對象改變的順序,決定對象的變化是否需要更新 gtid
通常 gtid 會卑記錄成下面格式
45eec521-2f34-11e0-0800-2a36050b826b:94530586304
言歸正傳,我們需要編譯 mariadb-mysql 及 galera 插件
galera/mysql 編譯步驟
<a target="_blank" href="https://downloads.mariadb.org/interstitial/mariadb-galera-5.5.33a/kvm-tarbake-jaunty-x86/mariadb-galera-5.5.33a.tar.gz/from/http://mirrors.scie.in/mariadb">https://downloads.mariadb.org/interstitial/mariadb-galera-5.5.33a/kvm-tarbake-jaunty-x86/mariadb-galera-5.5.33a.tar.gz/from/http://mirrors.scie.in/mariadb</a>
yum install -y cmake
tar xf mariadb-galera-5.5.33a.tar.gz
cd mariadb-5.5.33a/
cmake -lah
參考 cmakecache.txt 檔案中的配置資訊
cmake -dinstall_mysqldatadir:string=/mdb -dinstall_unix_addrdir:string=/var/run/mysqld/mysql5.socket
make
make install
預設情況下, mariadb 安裝在 /usr/local/mysql
galera 編譯
<a target="_blank" href="https://launchpad.net/galera/2.x/23.2.7/+download/galera-23.2.7-src.tar.gz">https://launchpad.net/galera/2.x/23.2.7/+download/galera-23.2.7-src.tar.gz</a>
添加資料源
baseurl=http://mirror.neu.edu.cn/fedora/epel//6server/x86_64/
添加下面軟體包
yum erase -y mysql.x86_64 mysql-devel.x86_64 mysql-libs.x86_64
yum install -y boost-devel.x86_64 libodb-boost-devel.x86_64 bzr scons
解壓 galera-23.2.7-src.tar.gz 并進行編譯
cd /usr/src
tar xf galera-23.2.7-src.tar.gz
cd galera-23.2.7-src
scons
注: scons 為編譯指令
編譯後能生成 libgalera_smm.so
複制編譯好的庫至下面位置 /usr/local/galera/lib/libgalera_smm.so
mkdir /usr/local/galera/lib -p
cp /usr/src/galera-23.2.7-src/libgalera_smm.so /usr/local/galera/lib/libgalera_smm.so
複制 啟動腳本 /usr/src/galera-23.2.7-src/scripts/mysql/mysql-galera 到 /usr/local
cp /usr/src/galera-23.2.7-src/scripts/mysql/mysql-galera /usr/local
建立 /usr/local/mysql/etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
big-tables
bind-address=0.0.0.0
character-set-server=utf8
datadir=/mdb
log-error=/var/log/mysqld/mysql5-error.log
socket=/var/run/mysqld/mysql5.socket
pid-file=/var/run/mysqld/mysql5.pid
port=3306
user=mysql
binlog_format = row
binlog_cache_size = 1m
character_set_server = utf8
collation_server = utf8_general_ci
default-storage-engine = innodb
expire_logs_days = 10
innodb_buffer_pool_size = 300m
innodb_thread_concurrency = 16
innodb_log_buffer_size = 8m
innodb_doublewrite = 1
innodb_file_per_table = 1
innodb_flush_log_at_trx_commit = 2
server-id = 1
max_connections = 1000
net_buffer_length = 8k
open-files-limit = 65535
wsrep_cluster_address = 'gcomm://192.168.200.163,192.168.200.171,172.18.8.49,172.18.8.50'
wsrep_provider = /usr/local/galera/lib/libgalera_smm.so
wsrep_retry_autocommit = 0
wsrep_sst_method = rsync
wsrep_provider_options="gcache.size=256m; gcache.page_size=256m"
wsrep_slave_threads=16
wsrep_cluster_name='my_cluster'
wsrep_node_name='db5'
wsrep_sst_auth=tt:tt123
maridb 啟動測試
初始化資料庫
mkdir /mdb
cd /usr/local/mysql
./scripts/install_mysql_db --datadir=/mdb
啟動腳本 /etc/rc.d/init.d/mysql5 確定檔案可執行權限
#!/bin/sh
# chkconfig: 2345 64 36
# description: a very fast and reliable sql database engine.
<p>basedir=/usr/local/mysql
datadir=/mdb</p><p># default value, in seconds, afterwhich the script should timeout waiting
# for server start.
# value here is overriden by value in my.cnf.
# 0 means don't wait at all
# negative numbers mean to wait indefinitely
service_startup_timeout=900
startup_sleep=1</p><p># lock directory for redhat / suse.
lockdir='/var/lock/subsys'
lock_file_path="$lockdir/mysql"</p><p># the following variables are only set for letting mysql.server find things.</p><p># set some defaults
mysqld_pid_file_path=/var/run/mysqld/mysql5.pid
if test -z "$basedir"
then
basedir=/usr/local/mysql
bindir=/usr/local/mysql/bin
if test -z "$datadir"
then
datadir=/usr/local/mysql/data
fi
sbindir=/usr/local/mysql/bin
libexecdir=/usr/local/mysql/bin
</p><p>else
bindir="$basedir/bin"
datadir="$basedir/data"
sbindir="$basedir/sbin"
if test -f "$basedir/bin/mysqld"
libexecdir="$basedir/bin"
else
libexecdir="$basedir/libexec"
fi</p><p># datadir_set is used to determine if datadir was set (and so should be
# *not* set inside of the --basedir= handler.)
datadir_set=</p><p>#
# use lsb init script functions for printing messages, if possible
#
lsb_functions="/lib/lsb/init-functions"
if test -f $lsb_functions ; then
. $lsb_functions
else
log_success_msg()
{
echo " success! $@"
}
log_failure_msg()
echo " error! $@"
fi</p><p>path="/sbin:/usr/sbin:/bin:/usr/bin:$basedir/bin"
</p><p>export path</p><p>mode=$1 # start or stop</p><p>[ $# -ge 1 ] && shift</p><p>
other_args="$*" # uncommon, but needed when called from an rpm upgrade action
# expected: "--skip-networking --skip-grant-tables"
# they are not checked here, intentionally, as it is the resposibility
# of the "spec" file author to give correct arguments only.</p><p>case `echo "testing\c"`,`echo -n testing` in
*c*,-n*) echo_n= echo_c= ;;
*c*,*) echo_n=-n echo_c= ;;
*) echo_n= echo_c='\c' ;;
esac</p><p>parse_server_arguments() {
for arg do
case "$arg" in
--basedir=*) basedir=`echo "$arg" | sed -e 's/^[^=]*=//'`
bindir="$basedir/bin"
if test -z "$datadir_set"; then
datadir="$basedir/data"
fi
sbindir="$basedir/sbin"
if test -f "$basedir/bin/mysqld"
then
libexecdir="$basedir/bin"
else
libexecdir="$basedir/libexec"
libexecdir="$basedir/libexec"
;;
--datadir=*) datadir=`echo "$arg" | sed -e 's/^[^=]*=//'`
datadir_set=1
</p><p> ;;
--pid-file=*) mysqld_pid_file_path=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
--service-startup-timeout=*) service_startup_timeout=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
esac
done
}</p><p>wait_for_pid () {
verb="$1" # created | removed
pid="$2" # process id of the program operating on the pid-file
pid_file_path="$3" # path to the pid file.</p><p> sst_progress_file=$datadir/sst_in_progress
i=0
avoid_race_condition="by checking again"</p><p> while test $i -ne $service_startup_timeout ; do</p><p> case "$verb" in
'created')
# wait for a pid-file to pop into existence.
test -s "$pid_file_path" && i='' && break
'removed')
# wait for this pid-file to disappear
test ! -s "$pid_file_path" && i='' && break
*)
echo "wait_for_pid () usage: wait_for_pid created|removed pid pid_file_path"
exit 1
esac</p><p> # if server isn't running, then pid-file will never be updated
if test -n "$pid"; then
if kill -0 "$pid" 2>/dev/null; then
: # the server still runs
</p><p> else
# the server may have exited between the last pid-file check and now.
if test -n "$avoid_race_condition"; then
avoid_race_condition=""
continue # check again.
fi</p><p> # there's nothing that will affect the file.
log_failure_msg "the server quit without updating pid file ($pid_file_path)."
return 1 # not waiting any more.
fi
fi</p><p> if test -e $sst_progress_file && [ $startup_sleep -ne 100 ];then
echo $echo_n "sst in progress, setting sleep higher"
startup_sleep=100
fi</p><p> echo $echo_n ".$echo_c"
i=`expr $i + 1`
sleep $startup_sleep</p><p> done</p><p> if test -z "$i" ; then
log_success_msg
return 0
log_failure_msg
return 1
}</p><p># get arguments from the my.cnf file,
# the only group, which is read from now on is [mysqld]
if test -x ./bin/my_print_defaults
</p><p> print_defaults="./bin/my_print_defaults"
elif test -x $bindir/my_print_defaults
print_defaults="$bindir/my_print_defaults"
elif test -x $bindir/mysql_print_defaults
print_defaults="$bindir/mysql_print_defaults"
# try to find basedir in /etc/my.cnf
conf=/usr/local/mysql/etc/my.cnf
print_defaults=
if test -r $conf
subpat='^[^=]*basedir[^=]*=\(.*\)$'
dirs=`sed -e "/$subpat/!d" -e 's//\1/' $conf`
for d in $dirs
do
d=`echo $d | sed -e 's/[ ]//g'`
if test -x "$d/bin/my_print_defaults"
then
print_defaults="$d/bin/my_print_defaults"
break
if test -x "$d/bin/mysql_print_defaults"
print_defaults="$d/bin/mysql_print_defaults"
done
fi</p><p> # hope it's in the path ... but i doubt it
test -z "$print_defaults" && print_defaults="my_print_defaults"
fi</p><p>#
# read defaults file from 'basedir'. if there is no defaults file there
</p><p># check if it's in the old (depricated) place (datadir) and read it from there
#</p><p>extra_args=""
if test -r "$basedir/my.cnf"
extra_args="-e $basedir/my.cnf"
if test -r "$datadir/my.cnf"
extra_args="-e $datadir/my.cnf"
fi</p><p>parse_server_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`</p><p>#
# set pid file if not given
if test -z "$mysqld_pid_file_path"
mysqld_pid_file_path=$datadir/`hostname`.pid
case "$mysqld_pid_file_path" in
/* ) ;;
* ) mysqld_pid_file_path="$datadir/$mysqld_pid_file_path" ;;
esac
fi</p><p>case "$mode" in
'start')
# start daemon</p><p> # safeguard (relative paths, core dumps..)
cd $basedir</p><p> echo $echo_n "starting mysql"
</p><p> if test -x $bindir/mysqld_safe
then
# give extra arguments to mysqld with the my.cnf file. this script
# may be overwritten at next upgrade.
$bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 &
wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?</p><p> # make lock for redhat / suse
if test -w "$lockdir"
touch "$lock_file_path"
fi</p><p> exit $return_value
else
log_failure_msg "couldn't find mysql server ($bindir/mysqld_safe)"
fi
;;</p><p> 'stop')
# stop daemon. we use a signal here to avoid having to know the
# root password.</p><p> if test -s "$mysqld_pid_file_path"
mysqld_pid=`cat "$mysqld_pid_file_path"`</p><p> if (kill -0 $mysqld_pid 2>/dev/null)
echo $echo_n "shutting down mysql"
kill $mysqld_pid
# mysqld should remove the pid file when it exits, so wait for it.
wait_for_pid removed "$mysqld_pid" "$mysqld_pid_file_path"; return_value=$?
else
log_failure_msg "mysql server process #$mysqld_pid is not running!"
rm "$mysqld_pid_file_path"
</p><p> # delete lock for redhat / suse
if test -f "$lock_file_path"
rm -f "$lock_file_path"
exit $return_value
log_failure_msg "mysql server pid file could not be found!"
;;</p><p> 'restart')
# stop the service and regardless of whether it was
# running or not, start it again.
if $0 stop $other_args; then
$0 start $other_args
log_failure_msg "failed to stop running server, so refusing to try to start."
exit 1
;;</p><p> 'reload'|'force-reload')
if test -s "$mysqld_pid_file_path" ; then
read mysqld_pid < "$mysqld_pid_file_path"
kill -hup $mysqld_pid && log_success_msg "reloading service mysql"
touch "$mysqld_pid_file_path"
log_failure_msg "mysql pid file could not be found!"
;;
'status')
# first, check to see if pid file exists
read mysqld_pid < "$mysqld_pid_file_path"
</p><p> if kill -0 $mysqld_pid 2>/dev/null ; then
log_success_msg "mysql running ($mysqld_pid)"
exit 0
log_failure_msg "mysql is not running, but pid file exists"
# try to find appropriate mysqld process
mysqld_pid=`pidof $libexecdir/mysqld`</p><p> # test if multiple pids exist
pid_count=`echo $mysqld_pid | wc -w`
if test $pid_count -gt 1 ; then
log_failure_msg "multiple mysql running but pid file could not be found ($mysqld_pid)"
exit 5
elif test -z $mysqld_pid ; then
if test -f "$lock_file_path" ; then
log_failure_msg "mysql is not running, but lock file ($lock_file_path) exists"
exit 2
fi
log_failure_msg "mysql is not running"
exit 3
log_failure_msg "mysql is running but pid file could not be found"
exit 4
'configtest')
# safeguard (relative paths, core dumps..)
cd $basedir
echo $echo_n "testing mysql configuration syntax"
daemon=$bindir/mysqld
if test -x $libexecdir/mysqld
daemon=$libexecdir/mysqld
elif test -x $sbindir/mysqld
daemon=$sbindir/mysqld
elif test -x `which mysqld`
daemon=`which mysqld`
log_failure_msg "unable to locate the mysqld binary!"
help_out=`$daemon --help 2>&1`; r=$?
if test "$r" != 0 ; then
log_failure_msg "$help_out"
log_failure_msg "there are syntax errors in the server configuration. please fix them!"
log_success_msg "syntax ok"
exit $r
'bootstrap')
# bootstrap the cluster, start the first node
# that initiate the cluster
echo $echo_n "bootstrapping the cluster"
$0 start $other_args --wsrep-new-cluster
;;
*)
# usage
basename=`basename "$0"`
echo "usage: $basename {start|stop|restart|reload|force-reload|status|configtest|bootstrap} [ mysql server options ]"
esac</p><p>exit 0
</p>
啟動每一台資料庫
service mysql5 start
在每台資料庫中建立下面使用者, 用于 sst 認證 (以 root 登入 mysql 資料庫後執行下面的 sql 語句)
grant usage on *.* to tt@'%' identified by 'tt123';
grant all privileges on *.* to tt@'%';
grant usage on *.* to tt@'localhost' identified by 'tt123';
grant all privileges on *.* to tt@'localhost';
flush privileges;
關閉所有資料庫, 叢集啟動前, 不需要啟動任何一台的資料庫
service mysql5 stop
建立并加入叢集
叢集中第一個節點啟動 (192.168.200.163)
建立軟連結,并啟動叢集,叢集啟動過程中會自動啟動 mariadb
ln -s /usr/local/mysql/bin/ /usr/local/mysql/sbin
cd /usr/local/
./mysql-galera -g gcomm:// start
測試是否成功啟動方法, 查詢是否會自動啟動 4567 端口
[root@db2 local]# netstat -ntl
active internet connections (only servers)
proto recv-q send-q local address foreign address state
tcp 0 0 0.0.0.0:3306 0.0.0.0:* listen
tcp 0 0 0.0.0.0:22 0.0.0.0:* listen
tcp 0 0 0.0.0.0:4567 0.0.0.0:* listen
登入 mysql 之後,查詢目前是否啟用 galera 插件
mariadb [(none)]> show status like 'wsrep_ready';
+---------------+-------+
| variable_name | value |
| wsrep_ready | on |
1 row in set (0.00 sec)
注,on 為已經啟動插件狀态
關閉方法
cd /usr/local
./mysql-galera stop
其他節點加入叢集方法
第一台 (192.168.200.163) 節點已經啟動成功
第二台 (192.168.200.171) 需要加入叢集
./mysql-galera -g gcomm://192.168.200.163 start
可按上述方法進行叢集啟動測試, 也可以參照下面方法, 觀察叢集位址是否增加兩個伺服器位址
mariadb [(none)]> show status like 'wsrep_incoming_addresses';
+--------------------------+-------------------------------------------+
| variable_name | value |
| wsrep_incoming_addresses | 192.168.200.171:3306,192.168.200.163:3306 |
第三台 (172.18.8.49) 需要加入叢集
./mysql-galera -g gcomm://192.168.200.163,192.168.200.171 start
第四台 (172.18.8.50) 需要加入叢集
./mysql-galera -g gcomm://192.168.200.163,192.168.200.171,172.18.8.49 start
注: 每次叢集啟動, 将會啟用資料同步機制,令每個叢集中的資料同步
假如,叢集工作期間,節點 3(172.18.8.49) 脫離叢集,重新開機,發生故障
而脫機期間,節點1,2,4 仍可繼續工作
當節點3 重新線上時,加入叢集前,将會自動進行資料同步
重新線上方法與上文中加入節點方法一緻
另外,假如覺得要定義所有的伺服器位址麻煩,可以加入叢集時候隻定義其中一台的位址,如 gcomm://192.168.200.163 叢集也能夠自動在加入後添加其他叢集 url位址
常見 wsrep 參數注釋
mariadb [terry]> show status like 'wsrep%';
+----------------------------+--------------------------------------+
| variable_name | value |
| wsrep_local_state_uuid | bb5b9e17-66c8-11e3-86ba-96854521d205 | uuid 叢集唯一标記
| wsrep_protocol_version | 4 |
| wsrep_last_committed | 16 | sql 送出記錄
| wsrep_replicated | 4 | 随着複制發出的次數
| wsrep_replicated_bytes | 692 | 資料複制發出的位元組數
| wsrep_received | 18 | 資料複制接收次數
| wsrep_received_bytes | 3070 | 資料複制接收的位元組數
| wsrep_local_commits | 4 | 本地執行的 sql
| wsrep_local_cert_failures | 0 | 本地失敗事務
| wsrep_local_bf_aborts | 0 |從執行事務過程被本地中斷
| wsrep_local_replays | 0 |
| wsrep_local_send_queue | 0 | 本地發出的隊列
| wsrep_local_send_queue_avg | 0.142857 | 隊列平均時間間隔
| wsrep_local_recv_queue | 0 | 本地接收隊列
| wsrep_local_recv_queue_avg | 0.000000 | 本地接收時間間隔
| wsrep_flow_control_paused | 0.000000 |
| wsrep_flow_control_sent | 0 |
| wsrep_flow_control_recv | 0 |
| wsrep_cert_deps_distance | 0.000000 | 并發數量
| wsrep_apply_oooe | 0.000000 |
| wsrep_apply_oool | 0.000000 |
| wsrep_apply_window | 1.000000 |
| wsrep_commit_oooe | 0.000000 |
| wsrep_commit_oool | 0.000000 |
| wsrep_commit_window | 1.000000 |
| wsrep_local_state | 4 |
| wsrep_local_state_comment | synced |
| wsrep_cert_index_size | 0 |
| wsrep_causal_reads | 0 |
| wsrep_incoming_addresses | 172.18.8.50:3306,172.18.8.49:3306 | 連接配接中的資料庫
| wsrep_cluster_conf_id | 18 |
| wsrep_cluster_size | 2 | 叢集成員個數
| wsrep_cluster_state_uuid | bb5b9e17-66c8-11e3-86ba-96854521d205 | 叢集 id
| wsrep_cluster_status | primary | 主伺服器
| wsrep_connected | on | 目前是否連接配接中
| wsrep_local_index | 1 |
| wsrep_provider_name | galera |
| wsrep_provider_vendor | codership oy <[email protected]> |
| wsrep_provider_version | 2.7(rxxxx) |
| wsrep_ready | on | 插件是否應用中
40 rows in set (0.05 sec)
時間關系,還沒有時間進行壓力測試,也沒有比對 galera 與 percona xtradb cluster 叢集之間差別
另,如使用 rpm 則十分友善,網路很多教程, 不較長的描述
auto_increment
當更多的 mariadb 加入到叢集之後,叢集中的資料庫會自動進行協調,并且自動定義偏移量, 這個比較人性化,自動化,如下描述
db1:
mariadb [(none)]> show variables like 'auto_increment%';
+--------------------------+-------+
| variable_name | value |
| auto_increment_increment | 4 |
| auto_increment_offset | 3 |
2 rows in set (0.00 sec)
db2:
| auto_increment_offset | 4 |
+------------------------
db3:
| auto_increment_offset | 2 |
db4:
| auto_increment_offset | 1 |
目前加入叢集中共 4 個節點, 如上所見,每個叢集中都會每次在數字遞增時候遞增 4 位, 而數字起始值為加入叢集的順序
模拟測試1
建立測試表
mariadb [(none)]> desc terry.t2;
+-------+-------------+------+-----+-------------------+-----------------------------+
| field | type | null | key | default | extra |
| id | int(11) | no | pri | null | auto_increment |
| name | varchar(20) | yes | | null | |
| time | timestamp | no | | current_timestamp | on update current_timestamp |
3 rows in set (0.00 sec)
在每台電腦中建立對應的資料插入腳本 (太大量的并發插入會導緻伺服器不斷脫離叢集,最終隻剩下一次,是以減少資料插入量)
[root@db6 mdb]# cat /tmp/in.sh
#!/bin/bash
for (( a=1 ; a<=1000 ; a++ ))
do
name="db6.$a"
mysql -u terry -p123 -e "insert into terry.t2 (name, time) values (\"$name\", now())"
done
目的:同時在 4 台電腦中進行資料插入,每台插入 1000 行(并發執行)
插入過程中, 會出現鎖,有一個資料庫叢集會自動脫離叢集 >_<"
mysql thread id 16, os thread handle 0x7f2f2019a700, query id 4666 applied write set 183192
table lock table `terry`.`t2` trx id 2d3ef lock mode ix
---transaction 2d3ee, active 0 sec
mysql tables in use 1, locked 1
1 lock struct(s), heap size 376, 0 row lock(s), undo log entries 1
mysql thread id 633, os thread handle 0x7f2f20076700, query id 4664 localhost terry query end
insert into terry.t2 (name, time) values ("db5.603", now())
table lock table `terry`.`t2` trx id 2d3ee lock mode ix
---transaction 2d3ed, active (prepared) 0 sec preparing
mysql thread id 3, os thread handle 0x7f2f3be4e700, query id 4662 committing 183190
參考其他三台 時間傳回值
db1 (使用 13 秒)
db2 (使用 24秒)
db3(使用14秒)
db4(寫入 35 條資料後 crash)