MySQL新版本選型
公司早期主要用mysql5.5這個版本秧均,今年我們把數據庫配置中心搭建起來食侮,主要推的是mysql5.6這個版本,性能和功能上都有了一定的提升目胡,mysql5.6也能支持gtid锯七,但是無法在線在gtid模式與普通模式之間切換,同時5.6的同步性能還是無法讓人滿意誉己,只能做到在多個db的情況啟動并行復制眉尸,業(yè)務上很難有這樣的保證,所以一旦寫操作密集的業(yè)務,同步慢就會是個嚴重的問題效五;
所以地消,最近一直在考慮升級MySQL,升級MySQL首先面臨的一個問題就是選一個合適的版本畏妖,首先我們考慮是的采用mysql5.7脉执,5.7今年已經連續(xù)發(fā)了多個正式版本了,目前使用范圍也比較廣戒劫,可以考慮在正式環(huán)境使用了半夷。于是我們進行了線上對比測試,發(fā)現mysql5.7與我們線上的mysql5.6版本的性能有較大的差距(也許還是有些參數沒有調好的原因迅细,5.7確實要復雜很多)巫橄。
與此同時,最近公司頻繁出現一些日志性存儲茵典,大多數都是采用innodb引擎湘换,容量非常浪費,另一方面由于我們公司的標準mysql服務器容量是1.3T左右统阿,對于一些大容量需求的業(yè)務來說彩倚,容量上也存在瓶頸,如果要保留長時間的數據就難以滿足需求了扶平。所以借此機會我們打算把這塊一起考慮進去帆离,目前Percona和Mariadb都支持Tokudb,Mariadb 10.2還是10.3也準備支持Myrocks了结澄。
于是決定對比試一下哥谷,選擇了Percona 5.7.14、Mariadb 10.1.18與我們線上的MySQL 5.6進行了對比測試麻献,經過壓測们妥。
首先是都使用Innodb引擎的情況:
Mariadb與MySQL5.6測試結果接近
Percona 5.7.14與官方MySQL5.7的性能結果差不多,比起MySQL5.6有一定的差距(去掉performance_schema好一點勉吻,但是也有差距)监婶。
采用Tokudb引擎測試的結果與官方聲稱的有差距,使用snappy壓縮的情況下餐曼,insert比innodb約慢1/4,update只有innodb的一半左右鲜漩。Percona性能更差源譬,就不考慮了。
最終選型Mariadb 10.1.18孕似,并且在線上部署了一個業(yè)務踩娘,通過這個業(yè)務慢慢試用以后,逐步推廣開來。
使用Mariadb踩到的一些坑
在使用Mariadb的過程中养渴,碰到了不少問題雷绢,這里主要提一下我碰到的兩個較大的問題,供大家參考:
1理卑、同步性能問題:
我們上的這個業(yè)務高峰期達到了9000多寫操作/秒翘紊,首先面臨的第一個問題就是同步性能跟不上,slave同步線程數加到了16個線程藐唠,勉強能追上帆疟,但是一旦數據庫從庫停一會,就有可能面臨永遠最不上的可能宇立。當快絕望的時候踪宠,看了一下mariadb的官方文章(https://mariadb.com/kb/en/mariadb/parallel-replication/),Mariadb的并行復制支持好幾種模式妈嘹,其中有in-order和out-of-order兩種柳琢,不過我們這個業(yè)務支持in-order,所以沒考慮out-of-order润脸,在in-order模式下柬脸,又支持兩種:Conservative 和 Optimistic,缺省情況下Conservative 津函,這種并行模式會嚴格保證事物的順序性肖粮,估計和5.7的group commit原理差不多;而Optimistic模式下尔苦,復制的時候會盡量啟動更多的會話涩馆,直到發(fā)現沖突時才會去處理沖突。果斷試了一下Optimistic允坚,非常強勁魂那,最高同步速度達到了14000次/秒。
2稠项、"內存泄露"
系統(tǒng)部署結構為:兩個Mariadb做成主主復制涯雅,在前面部署了一個自己開發(fā)的分布式數據庫,業(yè)務方連接到分布式數據庫進程展运。系統(tǒng)上線了幾天活逆,發(fā)現主庫會莫名其妙的掛掉,好在有分布式數據庫拗胜,并且會自動切換蔗候,Mariadb主庫掛了,會自動切到另外一個主庫上埂软,業(yè)務方沒有感知锈遥。查看內核日志,發(fā)現是OOM了,內核把MySQL殺掉了所灸。
于是開始了各種嘗試丽惶,去掉Tokudb引擎配置,換Mariadb 10.1.19 爬立,都嘗試過钾唬,最終都會發(fā)生主庫掛掉的事情。一次偶然的機會懦尝,我把主庫上的slave停掉了知纷,發(fā)現主庫的內存突然下降好多,并且內存不再增加了陵霉,但是一旦把主庫上的slave啟動就會發(fā)現琅轧,內存又逐漸身高。這種現象很像mysql線程內的內存分配機制造成的(基于mem_root的內存分配踊挠,線程停掉會全部釋放)乍桂,所以初步懷疑是這個原因造成的。發(fā)現作為雙主中的另外一個Mariadb效床,就不會出現內存上漲的問題睹酌。
發(fā)現上面的現象以后,就開始代碼上的調試剩檀,用gdb啟動一個mariadb憋沿,另外一個用普通命令啟動,這兩個庫做成雙主:
第一種情況:測試作為從庫的時候沪猴,接收到的binlog事件情況
在普通命令啟動的mariadb上插入一行數據辐啄,gdb查看接收到的事件的順序如下:
### i ) Gtid_log_event
### ii) Table_map_log_event
### iii) Write_rows_log_event
### iv) Xid_log_event
第二種情況:測試作為主庫的時候,接收到的binlog事件
在gdb啟動的mariadb上插入一行記錄运嗜,然后gdb觀察接收到的事件為:
### 1)Rotate_log_event
### 2)Gtid_list_log_event
### 3)Rotate_log_event
Rotate_log_event事件是虛擬出來的壶辜,用于讓主庫跟上從庫的同步位置,這基本上是一個空事件担租,沒有做任何處理砸民,所以初步懷疑是在處理Gtid_list_log_event事件的時候,出現了問題奋救。
反復查看Gtid_list_log_event::do_appy_event函數中的調用情況岭参,發(fā)現確實有些方法會調用thd->alloc來分配內存,但是沒有回收尝艘,所以造成內存不斷的增大演侯,我考慮了一下,因為是主庫對于同步性能要求也不高利耍,所以在Gtid_list_log_event::do_apply_event函數的最后加了一行代碼:free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC)); ?重新編譯后蚌本,跑了一天,內存終于穩(wěn)定了隘梨。
由于目前發(fā)現只有主庫有該事件程癌,主庫同步處理性能要求不高,所以暫時先這樣用著了轴猎。不知道m(xù)ariadb官方版本什么時候會優(yōu)化一下嵌莉。
總體來看,Mariadb還是比較適合我們公司的捻脖,它有最新的功能锐峭、特性能夠給我們提供很多解決方案。Tokudb可以解決日志型存儲的問題可婶;連接池可以解決大量連接情況下性能地下的問題沿癞;審計插件提供安全方面的審核;slave并發(fā)模式能夠提供高性能的復制能力矛渴。除了這些常見功能以外椎扬,Mariadb還提供了Cassandra插件、圖數據庫插件等等具温,這些都給我們給業(yè)務的服務增加了想象力蚕涤。