您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關(guān)MySQL中GTID的幾個(gè)限制和解決方案是怎樣的,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。
現(xiàn)在我看待一個(gè)技術(shù),總是會(huì)換一種角度來(lái)看,在他能實(shí)現(xiàn)什么的基礎(chǔ)上,我更喜歡看他不能做什么,為什么不能這么做。
比如MySQL GTID在5.6試水,5.7已經(jīng)發(fā)展完善,但是還是有一些場(chǎng)景是受限的。比如下面的兩個(gè)。
一個(gè)是create table xxx as select 的模式,另外一個(gè)是臨時(shí)表相關(guān)的。
今天我們就來(lái)簡(jiǎn)單說(shuō)說(shuō)這兩個(gè)場(chǎng)景。
GTID中create 語(yǔ)句限制的解法
create table xxx as select的語(yǔ)句,其實(shí)會(huì)被拆分為兩部分,create語(yǔ)句和insert語(yǔ)句,但是如果想一次搞定,MySQL會(huì)拋出如下的錯(cuò)誤。
mysql> create table test_new as select *from test;
ERROR 1786 (HY000): Statement violates GTID consistency: CREATE TABLE ... SELECT.
這種語(yǔ)句其實(shí)目標(biāo)明確,復(fù)制表結(jié)構(gòu),復(fù)制數(shù)據(jù),insert的部分好解決,難點(diǎn)就在于create table的部分,如果一個(gè)表的列有100個(gè),那么拼出這么一個(gè)語(yǔ)句來(lái)就是一個(gè)工程了。
我們也巧學(xué)巧用,看看MySQL有什么特別的方法來(lái)處理。
除了規(guī)規(guī)矩矩的拼出建表語(yǔ)句之外,還有一個(gè)方法是MySQL特有的用法 like。
create table xxx as select 的方式會(huì)被拆分成兩部分。
create table xxxx like data_mgr;
insert into xxxx select *from data_mgr;
臨時(shí)表的限制和考慮
另外一個(gè)看起來(lái)就有些蹊蹺了,看著文檔就是沒(méi)有什么好說(shuō)的,記住了就好,其實(shí)不然。
如果在事務(wù)中有臨時(shí)表的變動(dòng),很可能會(huì)導(dǎo)致數(shù)據(jù)不一致,這在MySQL的5.5版本中有相應(yīng)的bug,可以參見(jiàn)https://bugs.mysql.com/bug.php?id=76940
如果需要復(fù)現(xiàn),可以在找一套5.5的環(huán)境來(lái)模擬一下,分分鐘出效果。
我們創(chuàng)建兩個(gè)表t1,t2,然后建立兩個(gè)表之間的外鍵關(guān)聯(lián),作為 后續(xù)測(cè)試所用。
create table t1(c1 int primary key) engine=innodb;
insert into t1 values(1),(2),(3),(4),(5);
create table t2 (c1 int, c2 int, foreign key(c2) references t1(c1)) engine=innodb;
insert into t2 values(1,1),(2,2),(5,5);
創(chuàng)建臨時(shí)表
> create temporary table tmp as select * from t1;
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
模擬這個(gè)bug,開(kāi)啟事務(wù)。
> begin;
> drop temporary table if exists tmp;
Query OK, 0 rows affected (0.00 sec)
> delete from t1 where c1 > 2;
ERROR 1451 (23000): Cannot delete or update a parent row: a fore;
Query OK, 0 rows affected (0.00 sec)
然后使用mysqlbinlog來(lái)查看一下里面的信息??梢钥吹匠松厦娴呐R時(shí)表操作,后面的delete也會(huì)寫(xiě)入binlog
use `test`/*!*/;
SET TIMESTAMP=1499784283/*!*/;
DROP TEMPORARY TABLE IF EXISTS `tmp` /* generated by server */
/*!*/;
# at 300
# at 341
#170711 22:44:46 server id 13386 end_log_pos 341 Table_map: `test`.`t1` mapped to number 207
#170711 22:44:46 server id 13386 end_log_pos 380 Delete_rows: table id 207 flags: STMT_END_F
BINLOG '
XuRkWRNKNAAAKQAAAFUBAAAAAM8AAAAAAAEABHRlc3QAAnQxAAEDAAA=
XuRkWRlKNAAAJwAAAHwBAAAAAM8AAAAAAAEAAf/+AwAAAP4EAAAA
'/*!*/;
### DELETE FROM test.t1
### WHERE
### @1=3 /* INT meta=0 nullable=0 is_null=0 */
### DELETE FROM test.t1
### WHERE
### @1=4 /* INT meta=0 nullable=0 is_null=0 */
# at 380
#170711 22:44:49 server id 13386 end_log_pos 449 Query thread_id=176 exec_time=0 error_code=0
SET TIMESTAMP=1499784289/*!*/;
COMMIT
通過(guò)這個(gè)可以清晰的看到盡管已經(jīng)做了事務(wù)回滾,但是binlog還是會(huì)記錄下回滾的變更,這在某些場(chǎng)景中會(huì)觸發(fā)主從數(shù)據(jù)不一致。
而在GTID中,已經(jīng)做了這個(gè)檢查,歸根結(jié)底,還是cache里面的機(jī)制,大體來(lái)說(shuō),binlog有兩個(gè)cache來(lái)緩存事務(wù)的binlog:
binlog_cache_data stmt_cache; //存放非事務(wù)表和臨時(shí)表binlog
binlog_cache_data trx_cache; //存放事務(wù)表binlog
以上就是MySQL中GTID的幾個(gè)限制和解決方案是怎樣的,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。