Mariadb GTID
全局事務ID(Global transaction ID,GTID)為每個Event Group(就是一系列Event組成的一個原子單元,要么一起提交要么都無法提交)引入了一個標識,因此GTID是標識“事務”的最佳方式(盡管Event里面還包含一些非事務的DML語句和DDL,它們可以作為一個單獨的Event Group)。每當一個Event Group從Master復制到Slave時,它的GTID也通過GTID Event被傳到Slave。因為每個GTID在整個復制拓撲結構中都是一個唯一標志,所以這使得在不同的實例之間識別相同的Binlog Events非常簡單,然而在有GTID之前,想做到這點是很困難的。MariaDB從10.0.2開始提供GTID支持,但是MariaDB的GTID與MySQL的GTID在實現原理上并不相同,因為MariaDB支持像多源復制啊、多主復制等官方暫時還沒考慮的復制模型。
優勢
使用GTID有兩個主要的優勢:
1.在級聯復制、一主多從等復雜的復制場景下,可以更簡單地將一個Slave的復制修改到另一個Master上,而不用人工去尋找復制的起始位點。從5.0一路走來的同學應該很能理解這種痛苦。
這是因為Slave會保存最后一個執行的Event Group的GTID,因此可以通過這個GTID很容易地在新Master上找到相應的復制起點。而在使用Binlog File和Binlog Pos的時代,這是很難辦到的。
2.Slave的狀態是Crash-Safe的。
Slave的執行狀態(最后一個執行的GTID)被記錄在mysql.gtid_slave_pos系統表中。如果這張表使用的是事務引擎(例如InnoDB,默認就是),那么修改用戶表的數據和修改Slave狀態的系統表這兩個操作在就可以放在一個事務中完成,這就保證了Slave狀態是Crash-Safe的,如果Slave崩潰了,那么Crash Recovery就可以在重啟的時候把用戶數據表和Slave狀態系統表恢復到一個一致的位點。而在非GTID復制的舊版本中,這也是做不到的,Slave狀態只是簡單的存放在relay-log.info文件中(MySQL是可以把Binlog File和Binlog Pos也存在slave_relay_log_info和slave_master_info系統表中),而且需要靠不斷的fsync()調用才能同步到磁盤上,一旦宕機很可能導致Slave狀態跟實際不一致(但是也只有事務引擎的DML能保證一致,非事務引擎和DDL本身就不是Crash-Safe的)。
基于這兩個優勢,通常我們都建議使用GTID復制。并且傳統的基于Binlog文件位置的復制方式,和GTID的復制方式,在MariaDB中是可以相互之間平滑的切換的。
每個GTID,都包含三個數字部分,分別用’-‘號隔開,例如:
0-1-10
第一個數字’0’是Domain ID,這是一個32位的無符號整型。
第二個數字’1’是Server ID,這跟傳統的主備復制中Server ID的含義是一樣的,也是一個32位無符號整型。因此在一個復制拓撲中每個實例的Server ID必須是唯一的。
第三個數字是序列號(SequenceNumber)。這是一個64位的無符號整型。每個新產生的Event Group記錄到Binlog時都會新生成一個單調遞增的序列號。
這個規則使得(server_id, sequence_number)總是唯一的,因此GTID也是全局唯一的。
配置mariadb yum源
#?vim /etc/yum.repos.d/MariaDB10.repo
[mariadb]
name = MariaDB
baseurl =http://yum.mariadb.org/10.1/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
安裝mariadb
#?yum install -y MariaDB-server MariaDB-client tcl bzip2 lsof
創建mariadb 數據和日志目錄
#?mkdir -p /data/mysql/330{6,7}
#?mkdir -p /back/binlog/330{6,7}
#?chown -R mysql.mysql /data/mysql
#?chown -R mysql.mysql /back/binlog
創建多實例
#?mysql_install_db --datadir=/data/mysql/3306 --user=mysql
#?mysql_install_db --datadir=/data/mysql/3307 --user=mysql
Master3306配置文件,此處的配置是基礎配置,優化參數自行添加
#?vim /data/mysql/3306/my.cnf
[mysqld]
datadir=/data/mysql/3306
port=3306
socket=/data/mysql/3306/mysql.sock
slow-query-log=1??????????????????????? #開啟慢查詢日志
slow-query-log-file=/back/binlog/3306/mysql-slow.log #日志存儲位置
long_query_time=1????????????????????? #執行超過多長時間的sql會記錄下來
binlog_format=ROW???????????????????? #binlog日志格式
skip-name-resolve?????????????????????? #跳過域名解析
server-id=1
log-bin=/back/binlog/3306/master-bin
log-bin-index=/back/binlog/3306/master-bin.index
log-error=/back/binlog/3306/mysql-err.log
master-info-repository=TABLE
relay-log-info-repository=TABLE ? ? #此兩項為打開從服務器崩潰二進制日志功能,信息記錄在事物表而不是保存在文件
sync-master-info=1 ? ? #值為1確保信息不會丟失
slave-parallel-threads=2 ? ? #同時啟動多少個復制線程,最多與要復制的數據庫數量相等即可
binlog-checksum=CRC32 ? ? #效驗碼
master-verify-checksum=1 ? ? #啟動主服務器效驗
slave-sql-verify-checksum=1 ? ? #啟動從服務器效驗
binlog-rows-query-log-events=1 ? ? #用于在二進制日志詳細記錄事件相關的信息,可降低故障排除的復雜度;
[mysqld_safe]
pid-file=/data/mysql/3306/mysql.pid
[client-server]
socket=/data/mysql/3306/mysql.sock
Master 3307配置文件
#?vim /data/mysql/3307/my.cnf
[mysqld]
datadir=/data/mysql/3307
port=3307
socket=/data/mysql/3307/mysql.sock
slow-query-log=1?????????????? ?????????#開啟慢查詢日志
slow-query-log-file=/back/binlog/3307/mysql-slow.log #日志存儲位置
long_query_time=1????????????????????? #執行超過多長時間的sql會記錄下來
binlog_format=ROW???????????????????? #binlog日志格式
skip-name-resolve?????????????????????? #跳過域名解析
server-id=1
log-bin=/back/binlog/3307/master-bin
log-bin-index=/back/binlog/3307/master-bin.index
log-error=/back/binlog/3307/mysql-err.log
master-info-repository=TABLE
relay-log-info-repository=TABLE ? ? #此兩項為打開從服務器崩潰二進制日志功能,信息記錄在事物表而不是保存在文件
sync-master-info=1 ? ? ?#值為1確保信息不會丟失
slave-parallel-threads=2 ? ? #同時啟動多少個復制線程,最多與要復制的數據庫數量相等即可
binlog-checksum=CRC32 ? ? #效驗碼
master-verify-checksum=1 ? ?#啟動主服務器效驗
slave-sql-verify-checksum=1 ? ?#啟動從服務器效驗
binlog-rows-query-log-events=1 ? ?#用于在二進制日志詳細記錄事件相關的信息,可降低故障排除的復雜度;
[mysqld_safe]
pid-file=/data/mysql/3307/mysql.pid
[client-server]
socket=/data/mysql/3307/mysql.sock
Slave 3306配置文件
#?vim /data/mysql/3306/my.cnf
[mysqld]
datadir=/data/mysql/3306
port=3306
socket=/data/mysql/3306/mysql.sock
slow-query-log=1??????????????????????? #開啟慢查詢日志
slow-query-log-file=/back/binlog/3306/mysql-slow.log #日志存儲位置
long_query_time=1????????????????????? #執行超過多長時間的sql會記錄下來
binlog_format=ROW???????????????????? #binlog日志格式
skip-name-resolve?????????????????????? #跳過域名解析
server-id=2
log-bin=/back/binlog/3306/master-bin
log-bin-index=/back/binlog/3306/master-bin.index
log-error=/back/binlog/3306/mysql-err.log
master-info-repository=TABLE
relay-log-info-repository=TABLE ? ? #此兩項為打開從服務器崩潰二進制日志功能,信息記錄在事物表而不是保存在文件
sync-master-info=1 ? ? ?#值為1確保信息不會丟失
slave-parallel-threads=2 ? ? #同時啟動多少個復制線程,最多與要復制的數據庫數量相等即可
binlog-checksum=CRC32 ? ? #效驗碼
master-verify-checksum=1 ? ?#啟動主服務器效驗
slave-sql-verify-checksum=1 ? ?#啟動從服務器效驗
binlog-rows-query-log-events=1 ? ?#用于在二進制日志詳細記錄事件相關的信息,可降低故障排除的復雜度;
[mysqld_safe]
pid-file=/data/mysql/3306/mysql.pid
[client-server]
socket=/data/mysql/3306/mysql.sock
Slave 3307配置文件
#?vim /data/mysql/3307/my.cnf
[mysqld]
datadir=/data/mysql/3307
port=3307
socket=/data/mysql/3307/mysql.sock
slow-query-log=1??????????????????????? #開啟慢查詢日志
slow-query-log-file=/back/binlog/3307/mysql-slow.log #日志存儲位置
long_query_time=1????????????????????? #執行超過多長時間的sql會記錄下來
binlog_format=ROW???????????????????? #binlog日志格式
skip-name-resolve?????????????????????? #跳過域名解析
server-id=2
log-bin=/back/binlog/3307/master-bin
log-bin-index=/back/binlog/3307/master-bin.index
log-error=/back/binlog/3307/mysql-err.log
master-info-repository=TABLE
relay-log-info-repository=TABLE ? ?#此兩項為打開從服務器崩潰二進制日志功能,信息記錄在事物表而不是保存在文件
sync-master-info=1 ? ? #值為1確保信息不會丟失
slave-parallel-threads=2 ? ?#同時啟動多少個復制線程,最多與要復制的數據庫數量相等即可
binlog-checksum=CRC32 ? ? #效驗碼
master-verify-checksum=1 ? ? #啟動主服務器效驗
slave-sql-verify-checksum=1 ? ? #啟動從服務器效驗
binlog-rows-query-log-events=1 ? ?#用于在二進制日志詳細記錄事件相關的信息,可降低故障排除的復雜度;
[mysqld_safe]
pid-file=/data/mysql/3307/mysql.pid
[client-server]
socket=/data/mysql/3307/mysql.sock
3306啟動腳本
#?vim /etc/init.d/mysql3306
#init
port=3306
mysql_user="root"
mysql_pwd="123456"
CmdPath="/usr/bin"
#startup function
function_start_mysql()
{
printf "Starting MySQL...\n"
/bin/sh ${CmdPath}/mysqld_safe --defaults-file=/data/mysql/3306/my.cnf 2>&1 > /dev/null &
}
#stop function
function_stop_mysql()
{
printf "Stoping MySQL...\n"
${CmdPath}/mysqladmin -u ${mysql_user} -p${mysql_pwd} -S /data/mysql/3306/mysql.sock shutdown
}
#restart function
function_restart_mysql()
{
printf "Restarting MySQL...\n"
function_stop_mysql
sleep 2
function_start_mysql
}
case $1 in
start)
function_start_mysql
;;
stop)
function_stop_mysql
;;
restart)
function_restart_mysql
;;
*)
printf "Usage: /data/${port}/mysql {start|stop|restart}\n"
esac
3307啟動腳本
#?vim /etc/init.d/mysql3307
#init
port=3307
mysql_user="root"
mysql_pwd="123456"
CmdPath="/usr/bin"
#startup function
function_start_mysql()
{
printf "Starting MySQL...\n"
/bin/sh ${CmdPath}/mysqld_safe --defaults-file=/data/mysql/3307/my.cnf 2>&1 > /dev/null &
}
#stop function
function_stop_mysql()
{
printf "Stoping MySQL...\n"
${CmdPath}/mysqladmin -u ${mysql_user} -p${mysql_pwd} -S /data/mysql/3307/mysql.sock shutdown
}
#restart function
function_restart_mysql()
{
printf "Restarting MySQL...\n"
function_stop_mysql
sleep 2
function_start_mysql
}
case $1 in
start)
function_start_mysql
;;
stop)
function_stop_mysql
;;
restart)
function_restart_mysql
;;
*)
printf "Usage: /data/${port}/mysql {start|stop|restart}\n"
esac
啟動mariadb
#?chown -R mysql.mysql /data/mysql
#?chmod +x /etc/init.d/mysql330{6,7}
#?/etc/init.d/mysql3306 start
#?/etc/init.d/mysql3307 start
設置root密碼
#?mysqladmin -uroot password "123456" -S /data/mysql/3306/mysql.sock
#?mysqladmin -uroot password "123456" -S /data/mysql/3307/mysql.sock
添加開機啟動
#?vim /etc/rc.d/rc.local
/etc/init.d/mysql3306 start
/etc/init.d/mysql3307 start
#?chmod +x /etc/rc.local
安裝jemalloc
#?wgethttp://www.canonware.com/download/jemalloc/jemalloc-4.2.0.tar.bz2
#?tar -xjf jemalloc-4.2.0.tar.bz2
#?cd jemalloc-4.2.0
#?./configure --prefix=/usr/local/jemalloc --libdir=/usr/local/lib
#?make && make install
#?make clean
#?echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
#?/sbin/ldconfig
配置mariadb使用jemalloc
#?sed -i 's@executing mysqld_safe@executing mysqld_safe\nexport LD_PRELOAD=/usr/local/lib/libjemalloc.so@' /usr/bin/mysqld_safe
# lsof -n | grep jemalloc
配置GTID模式的主從
Master 3306創建主從同步用戶
#?mysql -uroot -p123456 -S /data/mysql/3306/mysql.sock
>grant replication slave,replication client on *.* to 'rep'@'192.168.1.%' identified by '123456';
>flush privileges;
導出數據庫,將導出的數據放到從庫上
#?mysqldump -uroot -p123456 -S /data/mysql/3306/mysql.sock -A > dataall-3306.sql
Master 3307創建主從同步用戶
#?mysql -uroot -p123456 -S /data/mysql/3307/mysql.sock
>grant replication slave,replication client on *.* to 'rep'@'192.168.1.%' identified by '123456';
>flush privileges;
導出數據庫,將導出的數據放到從庫上
#?mysqldump -uroot -p123456 -S /data/mysql/3307/mysql.sock -A > dataall-3307.sql
Slave 3306開啟主從同步
#?mysql -uroot -p123456 -S /data/mysql/3306/mysql.sock < dataall-3306.sql
#?mysql -uroot -p123456 -S /data/mysql/3306/mysql.sock
>CHANGE MASTER TO master_host="192.168.1.1", master_port=3306, master_user="rep",MASTER_PASSWORD='123456',master_use_gtid=slave_pos;
>start slave;
>show slave status\G;
Slave 3307開啟主從同步
#?mysql -uroot -p123456 -S /data/mysql/3307/mysql.sock < dataall-3307.sql
#?mysql -uroot -p123456 -S /data/mysql/3307/mysql.sock
>CHANGE MASTER TO master_host="192.168.1.1", master_port=3307, master_user="rep",MASTER_PASSWORD='123456',master_use_gtid=slave_pos;
>start slave;
>show slave status\G;
在數據庫重新初始化時,可能會出現輸入密碼無法登陸問題,需要重新設置密碼
#?vim my.cnf
skip-grant-tables
#?/etc/init.d/mysql3307 start
#?mysql -uroot -p -S /data/mysql/3307/mysql.sock
>use mysql
>update user set password = password("123456") where user = "root";
刪除my.cnf中的skip-grant-tables,重啟mysql就可以了
mysql鎖定所有表
> flush?tables?with?read?lock;
> unlock tables;
這個命令是全局讀鎖定,執行了命令之后所有庫所有表都被鎖定只讀,一般都是用在數據庫聯機備份,這個時候數據庫的寫操作將被阻塞,讀操作順利進行
mysql鎖定單個表
> lock tables tbl_name [AS alias] {read [local] | [low_priority] write}
> unlock tables;
這個命令是表級別的鎖定,可以定制鎖定某一個表,不影響其它表的寫操作
這兩個鎖表語句在執行的時候都需要注意個特點,就是隱式提交的語句,在退出mysql終端的時候都會隱式的執行unlock tables,也就是如果要讓表鎖定生效就必須一直保持會話