本篇文章給大家分享的是有關(guān)MySQL中GTID的幾個限制和解決方案是怎樣的,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
創(chuàng)新互聯(lián)自2013年創(chuàng)立以來,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目成都網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元棲霞做網(wǎng)站,已為上家服務(wù),為棲霞各地企業(yè)和個人服務(wù),聯(lián)系電話:13518219792
現(xiàn)在我看待一個技術(shù),總是會換一種角度來看,在他能實現(xiàn)什么的基礎(chǔ)上,我更喜歡看他不能做什么,為什么不能這么做。
比如MySQL GTID在5.6試水,5.7已經(jīng)發(fā)展完善,但是還是有一些場景是受限的。比如下面的兩個。
一個是create table xxx as select 的模式,另外一個是臨時表相關(guān)的。
今天我們就來簡單說說這兩個場景。
GTID中create 語句限制的解法
create table xxx as select的語句,其實會被拆分為兩部分,create語句和insert語句,但是如果想一次搞定,MySQL會拋出如下的錯誤。
mysql> create table test_new as select *from test;
ERROR 1786 (HY000): Statement violates GTID consistency: CREATE TABLE ... SELECT.
這種語句其實目標明確,復(fù)制表結(jié)構(gòu),復(fù)制數(shù)據(jù),insert的部分好解決,難點就在于create table的部分,如果一個表的列有100個,那么拼出這么一個語句來就是一個工程了。
我們也巧學(xué)巧用,看看MySQL有什么特別的方法來處理。
除了規(guī)規(guī)矩矩的拼出建表語句之外,還有一個方法是MySQL特有的用法 like。
create table xxx as select 的方式會被拆分成兩部分。
create table xxxx like data_mgr;
insert into xxxx select *from data_mgr;
臨時表的限制和考慮
另外一個看起來就有些蹊蹺了,看著文檔就是沒有什么好說的,記住了就好,其實不然。
如果在事務(wù)中有臨時表的變動,很可能會導(dǎo)致數(shù)據(jù)不一致,這在MySQL的5.5版本中有相應(yīng)的bug,可以參見https://bugs.mysql.com/bug.php?id=76940
如果需要復(fù)現(xiàn),可以在找一套5.5的環(huán)境來模擬一下,分分鐘出效果。
我們創(chuàng)建兩個表t1,t2,然后建立兩個表之間的外鍵關(guān)聯(lián),作為 后續(xù)測試所用。
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)建臨時表
> create temporary table tmp as select * from t1;
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
模擬這個bug,開啟事務(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來查看一下里面的信息。可以看到除了上面的臨時表操作,后面的delete也會寫入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
通過這個可以清晰的看到盡管已經(jīng)做了事務(wù)回滾,但是binlog還是會記錄下回滾的變更,這在某些場景中會觸發(fā)主從數(shù)據(jù)不一致。
而在GTID中,已經(jīng)做了這個檢查,歸根結(jié)底,還是cache里面的機制,大體來說,binlog有兩個cache來緩存事務(wù)的binlog:
binlog_cache_data stmt_cache; //存放非事務(wù)表和臨時表binlog
binlog_cache_data trx_cache; //存放事務(wù)表binlog
以上就是MySQL中GTID的幾個限制和解決方案是怎樣的,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。