662
技術社區[雲棲]
RDS最佳實踐(三)—如何製定相關的流程來規範RDS的使用
之前文章中,我們介紹了如何快速的把本地自建的數據庫遷移入雲,那是不是把數據庫遷移到RDS後,用戶就什麼都不需要做了?比如RDS幫你的數據庫做到了高可用,在主庫出現down機後能夠快速切換到備庫,立刻恢複應用;每天會定時的備份數據和日誌,如果出現誤操作能夠幫你恢複到任意時間點;如果擔心黑客攻擊或者sql注入漏洞,RDS能夠幫助你進行sql注入的攔截;當數據庫使用中出現bug時,後端有專業的源碼和DBA團隊幫助用戶實例打上patch,讓用戶無後顧之憂;當實例的性能出現瓶頸的時候,可以進行快速的彈性升級,保證服務的正常運行等等。
可以看到RDS已經具備相當豐富的自動化數據庫運維的功能,用戶不用太關心後端數據庫的運維,以前這些非常專業的DBA工作完完全全可以交由RDS係統來完成,那麼還需要用戶做什麼,是不是不需要用戶幹預了?答案是需要的,在日常的工單問題發現:
一. 經常會發現由於自己的開發人員誤操作導致用戶數據被誤刪除,雖然RDS支持恢複到任意時間點,但畢竟需要時間去恢複,會造成對用戶的影響;所以線上的操作務必謹慎,必須在測試環境中完全驗證後才能到線上執行,同時需要必要的數據備份;
二.開發人員發布了一個新功能,但是新功能中的一條sql語句沒有添加索引,導致了全表掃描,RDS的CPU,IO達到100%,影響了整個應用的響應時間;所以新發布的任何sql都必須進過嚴格的審核,添加上必要的索引;
三. 開發人員在業務高峰期對表進行一個表添加索引或者添加字段的操作(刪除數據),導致該表的其他訪問堵塞,影響前端應用;所以任何的線上操作都需要在業務的低峰期進行,生產變更必須嚴格控製在可允許的變更窗口內;
四.RDS實例由於時間到期後沒有及時進行處理,導致實例被鎖定或者釋放,雖然最終數據可以恢複回來,但這種故障的發生往往令人心驚膽寒;
所以需要用戶製定出合理的流程規範來使用RDS,比如設計開發過程中的數據庫流程規範,線下測試環境與線上生產環境數據的導入導出流程規範,線上數據訂正的流程規範,線上數據庫操作(添加字段,添加索引)的流程規範,數據庫上線下線的流程規範。
在阿裏巴巴數據庫技術團隊,即使有了非常自動化的運維平台,上述的這些流程製定也是開發,測試,DBA都必須遵守的,就是因為有了上述的這些流程才避免了很多不必要的故障發生,大大提高了整個平台的穩定性,除此之外還製定了運維紅線:
一.禁止在非變更窗口執行變更:
.所有的變更必須提前4小時提交申請,進過審批後才能執行操作;
.全網變更必須經過線下測試,線上小規模驗證後,才能全網推送;
.重大變更(數據庫停機,擴容,遷移)必須團隊review;
.數據訂正和數據提取必須經過團隊leader審核通過後才能進行操作;
二.安全保密:
.禁止未經正式審批進行查閱,變更,傳播,移動線上數據;
.禁止對無關人員提供係統登錄和發布權限;
數據庫開發規範:趕集網(國內互聯網公司)的DBA 吳詩展把自己多年的數據庫mysql運維開發檢驗總結了—MySQL數據庫開發的三十六條軍,對於很多的RDS用戶來說同樣是很受用的,包括了:基本軍規,字段軍規,索引軍規,SQL類軍規,約定類軍規,在此也很感謝他能夠把多年來的經驗總結分享給眾多的數據庫用戶,在這裏也在著重強調一些比較重要的規範:
一.表主鍵的設置:自增主鍵是你的最佳選擇
.在設計表的時候默認都添加一列無業務意義的自增id的主鍵:id bigint not null auto_increment;
.自增型主鍵以利於插入性能的提高
.自增型主鍵設計(int,bigint)可以降低二級索引的空間,提升二級索引的內存命中率;
.自增型的主鍵可以減小page的碎片,提升空間和內存的使用;
.無主鍵的表刪除,更新在row模式的主從架構,會導致備庫hang住;
二.引擎選擇:INNODB 引擎是你的最佳選擇
使用INNODB存儲引擎還是Myisam存儲引擎?
.RDS的內存配置innodb的innodb_buffer_pool_size,Myisam的key_cache配置32k;
.主機斷電,crash後Myisam表容易出現索引壞葉,需要手工repair修複索引;
.Myisam存儲引擎的表備份時候會被全局鎖住,導致無法寫入數據;
案例一:下麵的這幅圖片就是myisam引擎的表由於一個大查詢堵塞了該表的其他更新:
案例二:.FEDERATED 存儲引擎使用存在bug,會導致備份失敗
error log: >> log scanned up to (867972807) 130616 00:00:58 innobackupex-1.5.1: Continuing after ibbackup has suspended 130616 00:00:58 innobackupex-1.5.1: Starting mysql with options: –defaults-file=’/etc/my3015.cnf’ –password=xxxxxxxx –user=’Xtrabak’ –host=’127.0.0.1′ –port=’3015′ –unbuffered – 130616 00:00:58 innobackupex-1.5.1: Connected to database with mysql child process (pid=31437) 130616 00:01:00 innobackupex-1.5.1: Starting to lock all tables… >> log scanned up to (867972807) innobackupex-1.5.1: Error: mysql child process has died: ERROR 1160 (08S01) at line 7: Got an error writing communication packets while waiting for reply to MySQL request: ‘FLUSH TABLES WITH READ LOCK;’ at /usr/bin/innobackupex-1.5.1 line 381. 2013-06-16 00:01:06 [info]: Xtrabackup error,you can get detail from Logfile. 2013-06-16 00:01:06 [info]: ====================================== All backup finished . |
三.索引設計誤區:
誤區案例一:對查詢條件的每個字段建立單列索引
SQL查詢:
SELECT count(*) FROM order o WHERE is_send=0 AND
o.order_status in (0,1) AND o.shipping_status = 0 AND
o.is_separate > 0 and o.is_yushou=0 and o.sd_id=23
and o.add_time>= ’1370246433′ and o.add_time<= ’1370332842′
and o.jhd_id=0 group by o.order_id;
KEY:該表有近30個索引
PRIMARY KEY (order_id), UNIQUE KEY order_sn (order_sn), UNIQUE KEY deal_code (deal_code), KEY ind_user_id (user_id), KEY ind_shipping_id (shipping_id), KEY ind_pay_id (pay_id), KEY ind_agency_id (agency_id), KEY ind_extension_id (extension_id) , KEY ind_order_id (order_id), KEY ind_delivery_time (delivery_time) , KEY ind_invoice_no (invoice_no), KEY ind_user_nick (user_nick), KEY idx_cz_shipping_fee (cz_shipping_fee), KEY ind_mobile (mobile), KEY ind_order_info_sd (sd_id,is_send,add_time), KEY ind_order_info_status (shipping_status), KEY ind_order_pay_status (pay_status), KEY ind_order_is_yushou (is_yushou), KEY ind_order_dist_type (dist_type), KEY ind_order_jhd_id (jhd_id), KEY ind_order_is_send (is_send), KEY ind_order_ck_id(ck_id ), KEY ind_order_is_separate(is_separate), KEY ind_consignee (consignee), KEY ind_order_info_lylx (lylx,order_status,is_send); |
索引設計誤區二:對查詢的所有字段建立組合索引
09:44:03> show table status like ‘order’\G; *************************** 1. row *************************** Name: order Engine: InnoDB Version: 10 Row_format: Compact Rows: 5708209 Avg_row_length: 357 Data_length: 2042626048 Max_data_length: 0 Index_length: 9014607872 Data_free: 5242880 Auto_increment: NULL Create_time: 2013-04-09 22:56:57 Update_time: NULL Check_time: NULL Collation: utf8_bin Checksum: NULL Create_options: omment: 訂單表 該表的數據隻有2G,但是索引卻占用了9個G: |
KEY `idx_plt_taobao_order_dp_id` (`dp_id`,`customerno`,`created`,`endtime`,`pay_time`,`modified`,`consign_time`,`payment`,`status`,`type`,`total_fee`,`refund_fee`,`num`,`received_payment`,`trade_from`,`ccms_order_status`) KEY `idx_plt_taobao_order_created` (`created`,`customerno`,`endtime`,`pay_time`,`modified`,`consign_time`,`payment`,`status`,`type`,`total_fee`,`refund_fee`,`num`,`received_payment`,`trade_from`,`dp_id`,`ccms_order_status`) KEY `idx_plt_taobao_order_endtime` (`endtime`,`customerno`,`created`,`pay_time`,`modified`,`consign_time`,`payment`,`status`,`type`,`total_fee`,`refund_fee`,`num`,`received_payment`,`trade_from`,`dp_id`,`ccms_order_status`) KEY `idx_plt_taobao_order_pay_time` (`pay_time`,`customerno`,`created`,`endtime`,`modified`,`consign_time`,`payment`,`status`,`type`,`total_fee`,`refund_fee`,`num`,`received_payment`,`trade_from`,`dp_id`,`ccms_order_status`) |
希望這篇blog能夠對你使用RDS有所幫助.
最後更新:2017-04-03 08:26:18