1 Checksum
1.1 checksum原理
checksum table的原理是對表中的數據進行一行一行的較驗和計算,在執行checksum命令時,表會被加一個讀鎖(read lock),因此對於大表,這是一個很耗時的過程。
讀鎖:又叫S鎖/共享鎖;當MySQL的一個進程為某一表開啟讀鎖之后,其他的進程包含自身都沒有權利去修改這表表的內容。但是所有的進程還是可以讀出表里面的內容的。但是不能實現更新。
1.2 語法
在數據庫中輸入checksum table 庫.表;
說明:checksum無法對表結構,表屬性等進行檢查,只對表中的數據進行檢驗;
2 mysqldiff
mysqldiff該工具是官方mysql-utilities工具集的一個腳本,可以用來對比不同數據庫之間的表結構,或者同個數據庫間的表結構,並生成差異SQL語句。mysqldiff 是通過對象名稱(有表,索引,視圖,圖表,缺省值,規則,觸發器,用戶,函數,存儲過程等)來進行比較的;
2.1 mysqldiff安裝
#wget https://cdn.mysql.com/archives/mysql-utilities/mysql-utilities-1.6.5.tar.gz #tar xf mysql-utilities-1.6.5.tar.gz #cd mysql-utilities-1.6.5 #python setup.py build #python setup.py install #mysqldiff --version
2.2 語法
語法示例:
#mysqldiff --server1=user:pass@host:port:socket --server2=user:pass@host:port:socket db1.object1:db2.object1 db3:db4
這個語法有兩個用法:
db1.object1:db2.object1:如果指定了具體表對象,那么就會詳細對比兩個表的差異,包括表名、字段名、備注、索引、大小寫等所有的表相關的對象。
db3:db4:如果只指定數據庫,那么就將兩個數據庫中互相缺少的對象顯示出來,不比較對象里面的差異。這里的對象包括表、存儲過程、函數、觸發器等。
2.3 主要參數
- --server1:配置server1的連接。
- --server2:配置server2的連接。
- --character-set:配置連接時用的字符集,如果不顯示配置默認使用character_set_client。
- --width:配置顯示的寬度。
- --skip-table-options:保持表的選項不變,即對比的差異里面不包括表名、AUTO_INCREMENT(自增)、ENGINE(存儲引擎)、CHARSET(配置連接時用的字符集)等差異。
- -v, --verbose:控制顯示多少信息。例如,- v =冗長,-vv=更詳細,-vvv=調試;
- -d DIFFTYPE,--difftype=DIFFTYPE:差異的信息顯示的方式,有[unified|context|differ|sql],默認是unified。如果使用sql,那么就直接生成差異的SQL,這樣非常方便。
輸出類型,也就是difftype選項值:
(1)unified (默認)顯示統一的格式輸出;
(2)context以上下文格式輸出;
(3)differ以differ-style 格式輸出;
(4)sql以生成轉換SQL語句輸出;
- --changes-for=:修改對象。例如--changes-for=server2,那么對比以sever1為主,生成的差異的修改也是針對server2的對象的修改。
- --show-reverse:在生成的差異修改里面,同時會包含server2和server1的修改。
2.4 對比效果
注意:發現運行時需要用戶有spuer權限,否則無法運行,后面的工具都是如此;
示例1:
1)表test1和test2對比,顯示test2的不同,以及對test2的sql修改
1 mysqldiff --server1=root:0@localhost --server2=root:0@localhost --changes-for=server2 --difftype=sql study.test1:study.test2
注意:以SQL輸出的限制有:
1.對於分區表,如果分區表有差異,將對所有的改變生產。
2.ALTER TABLE 語句,顯示經過並省略分區差異。
3.事件重命名不支持。
4.不支持事務定義的條款。
5.不支持MySQL Cluster 的SQL擴展特性。
示例2:
(2)輸出類型對比,輸出類型,也就是difftype選項值:
1.unified (默認)顯示統一的格式輸出;
2.context以上下文格式輸出;
3.differ以differ-style 格式輸出;
4.sql以生成轉換SQL語句輸出;
1.輸出類型(默認)--difftype=unified; mysqldiff --server1=root:0@localhost --server2=root:0@localhost --changes-for=server2 study.test1:study.test2 2.輸出類型--difftype=context; mysqldiff --server1=root:0@localhost --server2=root:0@localhost --changes-for=server2 --difftype=context study.test1:study.test2 3.輸出類型--difftype=differ; mysqldiff --server1=root:0@localhost --server2=root:0@localhost --changes-for=server2 --difftype=differ study.test1:study.test2 4.輸出類型--difftype=sql; mysqldiff --server1=root:0@localhost --server2=root:0@localhost --changes-for=server2 --difftype=sql study.test1:study.test2
示例3:
如果需要生成SQL文件,加上輸出就可以;
mysqldiff --server1=root:0@localhost --server2=root:0@localhost --changes-for=server2 --difftype=sql study.test1:study.test2 > output.sql
3 mysqldbcompare
mysqldbcompare該工具是官方mysql-utilities工具集的一個腳本,可以用來檢查不同數據庫之間的數據一致性,檢查內容包括數據庫字符集、表結構、數據內容,只要有一個不一樣,則檢查不通過。
數據庫中的對象包括:表、視圖、觸發器、存儲過程、函數和事件。每一個對象類型計數可以使用-vv選項顯示。
3.1 mysqldbcompare安裝
#wget https://cdn.mysql.com/archives/mysql-utilities/mysql-utilities-1.6.5.tar.gz #tar xf mysql-utilities-1.6.5.tar.gz #cd mysql-utilities-1.6.5 #python setup.py build #python setup.py install #mysqldiff --version
說明:mysqldiff和mysqldbcompare都是mysql-utilities工具集的腳本,故只要一次安裝即可,兩個命令都有;
3.2 語法
語法示例:
#mysqldbcompare --server1=user:pass@host:port:socket --server2=user:pass@host:port:socket db1:db2
Mysqldbcompare和mysqldiff語法結構相似,可以參照mysqldiff;
3.3 主要參數
- --server1:MySQL服務器1配置。
- --server2:MySQL服務器2配置。如果是同一服務器,--server2可以省略。
- db1:db2:要比較的兩個數據庫。如果比較不同服務器上的同名數據庫,可以省略:db2。
- --all:比較所有兩服務器上所有的同名數據庫。--exclude排除無需比較的數據庫。
- --run-all-tests:運行完整比較,遇到第一次差異時不停止。
- --changes-for=:修改對象。例如--changes-for=server2,那么對比以sever1為主,生成的差異的修改也是針對server2的對象的修改。
- -d DIFFTYPE,--difftype=DIFFTYPE:差異的信息顯示的方式,有[unified|context|differ|sql],默認是unified。如果使用sql,那么就直接生成差異的SQL。
- -v, --verbose:控制顯示多少信息。例如,- v =冗長,-vv=更詳細,-vvv=調試;
- --show-reverse:在生成的差異修改里面,同時會包含server2和server1的修改。
- --skip-table-options:保持表的選項不變,即對比的差異里面不包括表名、AUTO_INCREMENT、ENGINE、CHARSET等差異。
- --skip-diff:跳過對象定義比較檢查。所謂對象定義,就是CREATE語句()里面的部分,--skip-table-options是()外面的部分。
- --skip-object-compare:默認情況下,先檢查兩個數據庫中相互缺失的對象,再對都存在對象間的差異。這個參數的作用就是,跳過第一步,不檢查相互缺失的對象。
- --skip-checksum-table:數據一致性驗證時跳過CHECKSUM TABLE。
- --skip-data-check:跳過數據一致性驗證。
- --skip-row-count:跳過字段數量檢查。
- --disable-binary-logging 如果服務器上啟用二進制日志,不想比較日志這步,可以使用選項來禁用。
3.4 對比效果
示例1:
庫study和study1對比,顯示study1的不同,以及對study1的sql修改 mysqldbcompare --server1=root:0@localhost --server2=root:0@localhost --changes-for=server2 --difftype=sql --run-all-tests study:study1
4 pt-table-checksum
pt-table-checksum其原理是在主庫執行基於statement的sql語句來生成主庫數據塊的checksum,把相同的sql語句傳遞到從庫執行,並在從庫上計算相同數據塊的checksum,最后,比較主從庫上相同數據塊的checksum值,由此判斷主從數據是否一致。檢測過程根據唯一索引將表按row切分為塊(chunk),以為單位計算,可以避免鎖表。檢測時會自動判斷復制延遲、 master的負載, 超過閥值后會自動將檢測暫停,減小對線上服務的影響。
4.1 安裝
#yum -y install perl-DBI perl-devel perl-DBD-MySQL perl-IO-Socket-SSL.noarch perl-Time-HiRes perl perl-Digest-MD5 perl-TermReadKey #wget https://www.percona.com/downloads/percona-toolkit/3.0.11/binary/tarball/percona-toolkit-3.0.11_x86_64.tar.gz #tar xf percona-toolkit-3.0.11_x86_64.tar.gz #cd percona-toolkit-3.0.11 #perl Makefile.PL #make #make install
4.2 常用參數
- --nocheck-replication-filters :不檢查復制過濾器,建議啟用。后面可以用--databases來指定需要檢查的數據庫。
- --no-check-binlog-format : 不檢查復制的binlog模式,要是binlog模式是ROW,則會報錯。
- --replicate-check-only :只顯示不同步的信息。
- --replicate= :把checksum的信息寫入到指定表中,建議直接寫到被檢查的數據庫當中。
- --create-replicate-table 選項會自動創建 percona.checksums 表
- --databases= :指定需要被檢查的數據庫,多個則用逗號隔開。
- --tables= :指定需要被檢查的表,多個用逗號隔開
- --empty-replicate-table:每個表checksum開始前,清空它之前的檢測數據(不影響其它表的checksum數據),默認yes。當然如果使用--resume啟動檢測數據不會清空。當啟用--noempty-replicate-table即不清空時,不計算計算chunk,只計算。
- --recursion-method:發現從庫的方式;
- h= :Master的地址
- u= :用戶名
- p=:密碼
- P= :端口
4.3 注意事項
1)第一次運行的時候需要加上--create-replicate-table參數,生成checksums表!!如果不加這個參數,那么就需要在對應庫下手工添加這張表了,表結構SQL如下:
create database db5; use db5; CREATE TABLE checksums ( db char(64) NOT NULL, tb1 char(64) NOT NULL, chunk int NOT NULL, chunk_time float NULL, chunk_index varchar(200) NULL, lower_boundary text NULL, upper_boundary text NULL, this_crc char(40) NOT NULL, this_cnt int NOT NULL, master_crc char(40) NULL, master_cnt int NULL, ts timestamp NOT NULL, PRIMARY KEY (db, tb1, chunk), INDEX ts_db_tb1 (ts, db, tb1) ) ENGINE=InnoDB;
2)授權
(1)根據測試,需要一個即能登錄主庫,也能登錄從庫的賬號;
(2)只能指定一個host,必須為主庫的IP;
(3)在檢查時會向表加S鎖(讀鎖/共享鎖);
(4)運行之前需要從庫的同步IO和SQL進程是YES狀態(show slave status\G;)。
4.4 pt-table-checksum使用梳理
(1)對特定表一致性進行檢查 pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=percona.checksums
--create-replicate-table --databases=study --tables=test1 h=192.168.122.65,u=jin,p=123456,P=3306
解釋:
TS :完成檢查的時間。
ERRORS :檢查時候發生錯誤和警告的數量。
DIFFS :0表示一致,1表示不一致。當指定--no-replicate-check時,會一直為0,當指定--replicate-check-only會顯示不同的信息。
ROWS :表的行數。
CHUNKS :被划分到表中的塊的數目。
SKIPPED :由於錯誤或警告或過大,則跳過塊的數目。
TIME :執行的時間。
TABLE :被檢查的表名。
(2)對特定數據庫的一致性進行檢查 pt-table-checksum --nocheck-replication-filters --replicate=percona.checksums --no-check-binlog-format
--databases=’study,study1’ h=192.168.122.65,u=jin,p=123456,P=3306
4.5 pt-table-sync用法梳理
如果通過pt-table-checksum 檢查找到了不一致的數據表,那么如何同步數據呢?即如何修復MySQL主從不一致的數據,讓他們保持一致性呢?
這時候可以利用另外一個工具pt-table-sync。
pt-table-sync: 高效的同步MySQL表之間的數據,他可以做單向和雙向同步的表數據。他可以同步單個表,也可以同步整個庫。它不同步表結構、索引、或任何其他模式對象。所以在修復一致性之前需要保證他們表存在。
(1)參數解釋:
- --replicate= :指定通過pt-table-checksum得到的表,這2個工具差不多都會一直用。
- --databases= : 指定執行同步的數據庫。
- --tables= :指定執行同步的表,多個用逗號隔開。
- --sync-to-master :指定一個DSN,即從的IP,他會通過show processlist或show slave status 去自動的找主。
- h= :服務器地址,命令里有2個ip,第一次出現的是Master的地址,第2次是Slave的地址。
- u= :帳號。
- p= :密碼。
- --print :打印,但不執行命令。
- --execute :執行命令。
(2) 示例語句
pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=percona.checksums
--databases=study --tables=test1 h=192.168.122.65,u=jin,p=123456,P=3306
pt-table-sync --replicate=percona.checksums h=192.168.122.65,u=jin,p=123456 h=192.168.122.67,u=jin,p=123456 --print --execute
建議:
修復數據的時候,最好還是用--print打印出來的好,這樣就可以知道那些數據有問題,可以人為的干預下。
不然直接執行了,出現問題之后更不好處理。總之還是在處理之前做好數據的備份工作。
如上修復后,再次檢查,發現主從庫數據已經一致了!
pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=percona.checksums
--databases=study --tables=test1 h=192.168.122.65,u=jin,p=123456,P=3306
問題說明:
在上面的操作中,在主庫里添加pt-table-checksum檢查的權限(從庫可以不授權)后,進行數據一致性檢查操作,會在操作的庫(實例中是study、study1)下產生一個checksums表!
這張checksums表是pt-table-checksum檢查過程中產生的。這張表一旦產生了,默認是刪除不了的,並且這張表所在的庫也默認刪除不了,刪除后過一會兒就又會出來。
參考鏈接:
https://www.cnblogs.com/kevingrace/p/6261091.html