<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 問題描述 表結構如下所示: ~~~ show create table test\G Table: test Create Table: CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `id2` varchar(50) DEFAULT NULL `id3` varchar(100) DEFAULT NULL `some_text` varchar(200) DEFAULT NULL `name` varchar(20) DEFAULT NULL `another_text` varchar(500) DEFAULT NULL `ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1024 DEFAULT CHARSET=utf8 ~~~ 對 mysql 執行如下語句: ~~~ select count(distinct(id2)) from santo_test where id3 = 'hahaha' group by substr(ctime, 0, 10) ~~~ 會導致mysql crash(signal 11)。 崩潰堆棧如下: ~~~ pthread_kill () handle_segfault (sig=11) <signal handler called> ptr_compare () queue_insert () merge_buffers() merge_many_buff() filesort() create_sort_index() JOIN::exec() mysql_select() handle_select() execute_sqlcom_select() mysql_execute_command() mysql_parse() ... ~~~ [官方bug傳送](https://bugs.mysql.com/bug.php?id=19660891)。 Bug復現小貼士 一條select語句搞掛MySQL Server? 當然還是需要苛刻條件的: * 需要保證 sort by/group by 的列本身是 CHAR(0) NOT NULL, 值也要多樣化, 不然會直接在優化器被優化掉; * 接著該列不能有索引, 確保邏輯走到filesort(在對索引列做GROUP BY/ORDER BY時直接走索引); * 之后要配備足夠小的`sort_buffer_size`, 和足夠量大的數據撐滿 sort_buffer,如@@sort_buffer_size = 32768時,40行數據就可以觸發; * 然后默默的給 substr 函數投喂錯誤的參數。 BOOM! 搞完破壞, 我們來看問題怎么解。 ## 成因解析 在看到觸發 crash 語句的時候,一定有讀者發現哪里不對了。這里使用的 substr(some_string, 0, some_length) 這樣的寫法,而官方文檔中 substr 函數的 @param2 實際上是從1開始計算,當起始位置置為0的時候,這條語句返回值其實是空的。當然,最終導致壓壞 mysql server 的一根稻草,正是這個長度為0的字符串。 現在我們沿著執行路線來探索 mysql 是如何一步步掛掉的,在 select 語句中使用 order by/group by 語句時,server 通常調用排序,主要通過索引或者 filesort 來實現排序,在 group by/order by 的列上不存在索引時,server 會選擇使用 filesort,其主要邏輯見 filesort.cc:filesort()。這里還會涉及到一個變量,`sort_buffer_size`,當需要排序的數據量超過?`sort_buffer_size`?大小時,server 會將數據劃分為 trunks,這時調用?`merge_many_buffers()`。隨后一路調用到 mysys/ptr_cmp.c 文件中的比較函數,這里的比較函數是按字節進行的,每四個字節為一個比較單位,當傳入的參數長度小于4時,會調用?`ptr_compare()`,而在上節的調用棧可以看到,最后 crash 就是在這個函數里。函數槽點如下: ~~~ static int ptr_compare(size_t *compare_length, uchar **a, uchar **b) { reg3 int length= *compare_length; reg1 uchar *first,*last; first= *a; last= *b; while ( --length) { if (*first++ != *last++) return (int) first[-1] - (int) last[-1]; } return (int) first[0] - (int) last[0]; } ~~~ 在 lengh == 0 時,while 里就會根本停不下來,直到被比較的兩位指針不停自加到一個不能訪問的內存區域,逼迫系統用 signal 11 殺死 mysql server。 ## 解決方案 比較長度為0的字符串本身是個意外, 所以解決方案就是添加一個輔助函數?`ptr_compare_length_zero`,在 length 為0時直接返回0,在做排序函數分派時,將長度為0的比較指派到`ptr_compare_length_zero`。 因此,想搞掛MySQL Server,這條路已經被堵上了,還是多修bug少搞破壞比較好 :-) 1. 官方fix1[60c6920509516a1e05b855799479a59c27803191](https://github.com/mysql/mysql-server/commit/60c6920509516a1e05b855799479a59c27803191) 2. 官方fix2?[b62c5daa646434290c9b2d1c9b162487cb8edf04](https://github.com/mysql/mysql-server/commit/b62c5daa646434290c9b2d1c9b162487cb8edf04) 3. [MySQL · 社區動態 · MySQL5.6.26 ReleaseNote解讀](http://mysql.taobao.org/monthly/2015/08/03/)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看