整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          技術(shù)分享 - MySQL 內(nèi)部臨時表是怎么存放的

          技術(shù)分享 - MySQL 內(nèi)部臨時表是怎么存放的

          者:胡呈清


          愛可生 DBA 團(tuán)隊成員,擅長故障分析、性能優(yōu)化,個人博客:https://www.jianshu.com/u/a95ec11f67a8,歡迎討論。


          本文來源:原創(chuàng)投稿


          *愛可生開源社區(qū)出品,原創(chuàng)內(nèi)容未經(jīng)授權(quán)不得隨意使用,轉(zhuǎn)載請聯(lián)系小編并注明來源。


          如果 SQL 在執(zhí)行過程中讀到的數(shù)據(jù)無法直接得到結(jié)果,那么就需要額外的內(nèi)存來保存中間結(jié)果,得出最終結(jié)果,這個額外的內(nèi)存就是內(nèi)部臨時表。比如 group by 執(zhí)行時,就需要構(gòu)建一個臨時表,需要額外的字段保存聚合函數(shù)的結(jié)果,當(dāng)然為了防止內(nèi)存使用過大,一般超出某個限制后就會放到磁盤上。關(guān)于哪些操作會產(chǎn)生內(nèi)部臨時表,可以查看官方文檔:https://dev.mysql.com/doc/refman/8.0/en/internal-temporary-tables.html,下面主要介紹 MySQL8.0 內(nèi)部臨時表存放方式的變化。

          MySQL 5.6

          MySQL 5.6 中,內(nèi)部臨時表大小超過內(nèi)存限制后是在臨時目錄中的單個表文件表空間中創(chuàng)建的,如果禁用了 innodb_file_per_table ,則在數(shù)據(jù)目錄中的 InnoDB 共享表空間(ibdata1)中創(chuàng)建,很容易造成 ibdata1 過大,并且無法釋放,只能邏輯導(dǎo)出數(shù)據(jù)遷移到新實(shí)例解決。

          MySQL 5.7

          MySQL 5.7 在臨時表空間上做了改進(jìn),已經(jīng)實(shí)現(xiàn)將臨時表空間從 InnoDB 共享表空間或者獨(dú)立表空間中分離,現(xiàn)在叫共享臨時表空間。好處有二:

          1. 可以消除為每個臨時表創(chuàng)建和刪除的性能成本;
          2. 是一塊單獨(dú)為內(nèi)部臨時表劃分的表空間,重啟 mysqld 可以重置其大小,避免 MySQL5.6 時 ibdata1 難以釋放的問題。

          其表現(xiàn)是 MySQL 啟動時 datadir 下會創(chuàng)建一個 ibtmp1 文件,默認(rèn)值下會無限擴(kuò)展。例如,如果某個 SQL 執(zhí)行時創(chuàng)建了一個大小為 20MB 的內(nèi)部磁盤臨時表,則創(chuàng)建時默認(rèn)大小為 12MB 的臨時表空間文件會擴(kuò)展到 20MB 以適應(yīng)該表。當(dāng) SQL 執(zhí)行完刪除臨時表時,釋放的空間可以重新用于新的臨時表,但 ibtmp1 文件保持?jǐn)U展大小,只有重啟 MySQL 時才會真正回收共享臨時表空間變成初始大小 12MB。

          相關(guān)參數(shù):

          • tmp_table_size&max_heap_table_size,內(nèi)部臨時表是存在內(nèi)存中的,使用 MEMORY 存儲引擎,如果大小超過了這兩者較小的值,則會轉(zhuǎn)化為磁盤臨時表;
          • internal_tmp_disk_storage_engine:如果內(nèi)部臨時表轉(zhuǎn)化為磁盤臨時表,則這個參數(shù)指定了磁盤臨時表的存儲引擎,默認(rèn)是 INNODB,還可以設(shè)置為 MYISAM;
          • innodb_temp_data_file_path:指定了臨時表空間的位置和大小,默認(rèn)值為 ibtmp1:12M:autoextend ,即 datadir/ibtmp1,初始大小12M可以無限擴(kuò)展,建議限制一個最大值防止把磁盤撐滿。

          缺點(diǎn):SQL 執(zhí)行完產(chǎn)生的內(nèi)部臨時表可能很大,必須要重啟才能釋放。這點(diǎn)曾一度讓我很困惑,為什么不能做的更好一點(diǎn)執(zhí)行完就釋放呢?所幸 MySQL8.0 優(yōu)化了這個問題。

          MySQL 8.0

          MySQL 8.0又有較大變化,新增了一些參數(shù):

          • internal_tmp_mem_storage_engine:用來指定在內(nèi)存中的內(nèi)部臨時表的存儲引擎,默認(rèn)值 TempTable,而非以前默認(rèn)的 MEMORY
          • temptable_max_ram:定義 TempTable 存儲引擎開始在磁盤上存儲數(shù)據(jù)之前可以占用的最大內(nèi)存量,默認(rèn)值1G
          • temptable_use_mmap:定義當(dāng) TempTable 存儲引擎占用的內(nèi)存量超過 temptable_max_ram 變量定義的限制時,TempTable 存儲引擎是否為內(nèi)存中的內(nèi)部臨時表分配空間作為內(nèi)存映射的臨時文件。 禁用 temptable_use_mmap 時,將使用 InnoDB 磁盤內(nèi)部臨時表代替。默認(rèn)值ON,8.0.16引入,8.0.26棄用。
          • temptable_max_mmap:定義 TempTable 存儲引擎在開始將數(shù)據(jù)存儲到磁盤上的 InnoDB 內(nèi)部臨時表之前,被允許從內(nèi)存映射的臨時文件分配的最大內(nèi)存量(以字節(jié)為單位)。設(shè)置為0將禁用從內(nèi)存映射的臨時文件分配內(nèi)存。默認(rèn)值1G,8.0.23引入。

          內(nèi)存映射臨時文件

          也就是說,默認(rèn)情況下執(zhí)行 SQL 產(chǎn)生內(nèi)部臨時表,使用的存儲引擎從 MEMORY 變成了 TempTable,當(dāng)然 TempTable 依然是一種內(nèi)存表,可以使用的最大內(nèi)存是1G(默認(rèn))。當(dāng)大小超過1G,會使用內(nèi)存映射臨時文件作為內(nèi)部臨時表的溢出機(jī)制,大白話就是防止內(nèi)存使用太大,把內(nèi)存中的數(shù)據(jù)放在臨時文件中。

          但是你想想,關(guān)系型數(shù)據(jù)庫設(shè)計了存儲引擎這么好的東西來存放數(shù)據(jù),這時候用文件來存是不是過分了點(diǎn)?估計官方是這么想的:哎呀內(nèi)部臨時表很小的,我就臨時放放,你忍忍。后來發(fā)現(xiàn)有些內(nèi)部臨時表太大了忍不了,為了防止內(nèi)存映射臨時文件過大,8.0.23版本引入一個新參數(shù) temptable_max_mmap 來限制其大小,如果超過其大小(默認(rèn)1G),則轉(zhuǎn)化為磁盤臨時表(這點(diǎn)和 MySQL 5.7一致)。值得注意的是 temptable_use_mmap 參數(shù) 8.0.26 標(biāo)記被棄用了,官方文檔也提示建議設(shè)置為0將其關(guān)閉,所以個人理解使用內(nèi)存映射臨時文件作為內(nèi)部臨時表的溢出機(jī)制是一個糟糕的方案。

          TempTable

          為什么要把內(nèi)部臨時表默認(rèn)引擎換成 TempTable ?它與 MEMORY 最大的不同是:

          • 可以支持變長類型,例如 varchar(100)的數(shù)據(jù)”abcd”應(yīng)該只占用4個字節(jié)而非100個字節(jié),節(jié)省內(nèi)存;
          • 支持二進(jìn)制大對象,例如 blob, text 等。如果使用 MEMORY 引擎,這樣的內(nèi)部臨時表會直接使用磁盤臨時表,這個是為了提升性能。

          那么真的那么好用嗎?目前最新版本是8.0.26,還是存在一些問題的,例如: https://bugs.mysql.com/bug.php?id=98782 https://bugs.mysql.com/bug.php?id=98739 https://bugs.mysql.com/bug.php?id=99593 https://bugs.mysql.com/bug.php?id=99100

          前3個都是性能問題,后面一個則可能會導(dǎo)致 SQL 執(zhí)行時報錯:The table '/tmp/#sql639b7_13_4' is full,所以在這些問題解決前,建議設(shè)置internal_tmp_mem_storage_engine=MEMORY

          臨時表空間

          MySQL 8.0 臨時表空間也發(fā)生了變化,分為了會話臨時表空間全局臨時表空間內(nèi),全局臨時表空間內(nèi)和 MySQL 5.7 時沒什么兩樣,不過 SQL 產(chǎn)生的內(nèi)部臨時表將存儲在會話臨時表空間中。

          新參數(shù):

          • innodb_temp_tablespaces_dir :定義了創(chuàng)建會話臨時表空間的位置,默認(rèn)位置是數(shù)據(jù)目錄中 #innodb_temp的目錄
          shell> ls datadir/#innodb_temp
          temp_10.ibt  temp_2.ibt  temp_4.ibt  temp_6.ibt  temp_8.ibt
          temp_1.ibt   temp_3.ibt  temp_5.ibt  temp_7.ibt  temp_9.ibt
          

          會話臨時表空間其實(shí)是個包含10個臨時表空間的池,會話臨時表空間在第一次請求創(chuàng)建磁盤臨時表時從臨時表空間池中分配給會話。一個會話最多分配兩個表空間,一個用于用戶創(chuàng)建的臨時表,另一個用于優(yōu)化器創(chuàng)建的內(nèi)部臨時表。當(dāng)會話斷開連接時,其臨時表空間被清除并釋放回池中。

          測試現(xiàn)象

          temptable_use_mmap=ON 時,如果內(nèi)部臨時表超過了 temptable_max_ram 大小,使用內(nèi)存映射的臨時文件用作內(nèi)部臨時表的溢出機(jī)制,臨時文件放在 tmpdir 目錄下:

          可以看到臨時文件數(shù)量+1,磁盤臨時表數(shù)量不變:

          temptable_use_mmap=OFF 時,如果內(nèi)部臨時表超過了temptable_max_ram 大小,使用 InnoDB 磁盤內(nèi)部臨時表用作內(nèi)部臨時表的溢出機(jī)制,存放在 innodb 會話臨時表空間中,與 MySQL 5.7 的區(qū)別是,session 斷開后就會釋放空間,不需要重啟 MySQL :

          可以看到臨時文件數(shù)量不變,磁盤臨時表數(shù)量+1:

          者:小不點(diǎn)啊

          來源:www.cnblogs.com/leeSmall/p/9356535.html

          一、Nginx Rewrite 規(guī)則


          1. Nginx rewrite規(guī)則


          Rewrite規(guī)則含義就是某個URL重寫成特定的URL(類似于Redirect),從某種意義上說為了美觀或者對搜索引擎友好,提高收錄量及排名等。


          語法:


          rewrite <regex> <replacement> [flag]
          關(guān)鍵字 || 正則 || 替代內(nèi)容 || flag標(biāo)記


          Rewrite規(guī)則的flag標(biāo)記主要有以下幾種:


          • last :相當(dāng)于Apache里的(L)標(biāo)記,表示完成rewrite;
          • break:本條規(guī)則匹配完成后,終止匹配,不再匹配后面的規(guī)則
          • redirect:返回302臨時重定向,瀏覽器地址會顯示跳轉(zhuǎn)后的URL地址
          • permanent:返回301永久重定向,瀏覽器地址欄會顯示跳轉(zhuǎn)后的URL地址


          last和break用來實(shí)現(xiàn)URL重寫,瀏覽器地址欄URL地址不變


          2. Nginx rewrite例子


          a) 例如用戶訪問www.dbspread.com,想直接跳轉(zhuǎn)到網(wǎng)站下面的某個頁面,www.dbspread.com/new.index.html如何來實(shí)現(xiàn)呢?我們可以使用Nginx Rewrite 來實(shí)現(xiàn)這個需求,具體如下:在server中加入如下語句即可:


          效果圖如下:

                          rewrite     ^/$    http://www.dbspread.com/new.index.html  permanent;
          對應(yīng)如下語法:
                          rewrite    <regex>    <replacement>                 [flag];
                          關(guān)鍵字      正則        替代內(nèi)容                    flag標(biāo)記

          正則表達(dá)式說明:

          *代表前面0或更多個字符                +代表前面1或更多個字符
          ?代表前面0或1個字符                  ^代表字符串的開始位置
          $代表字符串結(jié)束的位置                 。為通配符,代表任何字符

          b)例如多個域名跳轉(zhuǎn)到同一個域名,nginx rewrite規(guī)則寫法如下:


          格式:

          rewrite <regex> <replacement> [flag];
          關(guān)鍵字 || 正則 || 替代內(nèi)容 || flag標(biāo)記


          說明:


          • rewrite為固定關(guān)鍵字,表示開始進(jìn)行rewrite匹配規(guī)則、
          • regex部分是 ^/(.*) ,這是一個正則表達(dá)式,匹配完整的域名和后面的路徑地址
          • replacement部分是http://www.dbspread.com/,是取自regex部分( )里的內(nèi)容。匹配成功后跳轉(zhuǎn)到的URL。
          • flag部分 permanent表示永久301重定向標(biāo)記,即跳轉(zhuǎn)到新的 http://www.dbspread.com/ 地址上



          二、Nginx 防盜鏈


          1. 什么是防盜鏈


          比如http://www.dbspread.com/download/av123.rmvb 這個視頻下載地址被其他網(wǎng)站引用,比如在www.test.com的index.html引用download/av123.rmvb就叫盜鏈,我們要禁止這種引用就叫做防盜鏈



          2. 怎么實(shí)現(xiàn)防盜鏈


          在nginx的nginx.conf的server里面配置如下代碼


          三、Nginx 動靜分離

          1. 動靜分離是什么

          Nginx動靜分離是讓動態(tài)網(wǎng)站里的動態(tài)網(wǎng)頁根據(jù)一定規(guī)則把不變的資源和經(jīng)常變的資源區(qū)分開來,動靜資源做好了拆分以后,我們就可以根據(jù)靜態(tài)資源的特點(diǎn)將其做緩存操作,這就是網(wǎng)站靜態(tài)化處理的核心思路。

          2. 動靜分離原理圖

          3. Nginx動靜分離應(yīng)該注意的地方

          1). WEB項(xiàng)目開發(fā)時要注意,將靜態(tài)資源盡量放在一個static文件夾2). 將static靜態(tài)資源文件夾放到Nginx可以取到的位置3). 頁面要建立全局變量路徑,方便修改路徑4). 修改nginx.conf的location, 匹配靜態(tài)資源請求

          4. Nginx動靜分離步驟

          4.1 準(zhǔn)備一個靜態(tài)資源button.css

          body {
              margin: 10px 20px;
              text-align: center;
              font-family: Arial, sans-serif;
              background-color: red;
          }

          4.2 在/var/local下新建一個static文件夾用來存放靜態(tài)資源button.css

          4.3 在tomcat-8080/webapps/ROOT下的index.html里面引入button.css


          4.4 在nginx的nginx.conf中server節(jié)點(diǎn)新增靜態(tài)資源分離的配置


          對于Nginx基礎(chǔ)配置,推薦之前的:后端實(shí)踐:Nginx日志配置(超詳細(xì))

          4.5 訪問頁面查看效果

          四、Nginx+keepalived 實(shí)現(xiàn)高可用

          1. keepalived是什么

          Keepalived軟件起初是專為LVS負(fù)載均衡軟件設(shè)計的,用來管理并監(jiān)控LVS集群系統(tǒng)中各個服務(wù)節(jié)點(diǎn)的狀態(tài),后來又加入了可以實(shí)現(xiàn)高可用的VRRP (Virtual Router Redundancy Protocol ,虛擬路由器冗余協(xié)議)功能。因此,Keepalived除了能夠管理LVS軟件外,還可以作為其他服務(wù)(例如:Nginx、Haproxy、MySQL等)的高可用解決方案軟件

          2. keepalived主要功能

          管理LVS負(fù)載均衡軟件實(shí)現(xiàn)LVS集群節(jié)點(diǎn)的健康檢查作為系統(tǒng)網(wǎng)絡(luò)服務(wù)的高可用性(failover)

          3. keepalived故障轉(zhuǎn)移

          Keepalived高可用服務(wù)之間的故障切換轉(zhuǎn)移,是通過 VRRP 來實(shí)現(xiàn)的。在 Keepalived服務(wù)正常工作時,主 Master節(jié)點(diǎn)會不斷地向備節(jié)點(diǎn)發(fā)送(多播的方式)心跳消息,用以告訴備Backup節(jié)點(diǎn)自己還活著,當(dāng)主 Master節(jié)點(diǎn)發(fā)生故障時,就無法發(fā)送心跳消息,備節(jié)點(diǎn)也就因此無法繼續(xù)檢測到來自主 Master節(jié)點(diǎn)的心跳了,于是調(diào)用自身的接管程序,接管主Master節(jié)點(diǎn)的 IP資源及服務(wù)。而當(dāng)主 Master節(jié)點(diǎn)恢復(fù)時,備Backup節(jié)點(diǎn)又會釋放主節(jié)點(diǎn)故障時自身接管的IP資源及服務(wù),恢復(fù)到原來的備用角色。

          說明:keepalived的主從切換和redis的主從切換是不一樣的,keepalived的主節(jié)點(diǎn)掛了以后,從節(jié)點(diǎn)變?yōu)橹鞴?jié)點(diǎn),之前的主節(jié)點(diǎn)恢復(fù)以后繼續(xù)做主節(jié)點(diǎn)。redis的主節(jié)點(diǎn)掛了以后,重新恢復(fù)以后變?yōu)閺墓?jié)點(diǎn)

          4. keepalived高可用架構(gòu)示意圖

          說明:

          虛擬ip(VIP):192.168.152.200,對外提供服務(wù)的ip,也可稱作浮動ip192.168.152.130:nginx + keepalived master 主192.168.152.129:nginx + keepalived backup 從192.168.152.129:tomcat-8080192.168.152.129:tomcat-8081

          5. keepalived安裝

          環(huán)境準(zhǔn)備:

          centos6、jdk

          虛擬ip(VIP):192.168.152.200,對外提供服務(wù)的ip,也可稱作浮動ip
          192.168.152.130:nginx + keepalived master 主
          192.168.152.129:nginx + keepalived backup 從
          192.168.152.129:tomcat-8080
          192.168.152.129:tomcat-8081

          nginx和tomcat的環(huán)境準(zhǔn)備請查看我的前一篇關(guān)于nginx的文章

          5.1 安裝keepalived的步驟:

          注:192.168.152.129(keepalived從節(jié)點(diǎn)) 與 192.168.152.130(keepalived主節(jié)點(diǎn))先安裝好nginx + keepalived

          下載壓縮包:

          wget www.keepalived.org/software/keepalived-1.3.5.tar.gz

          解壓縮:

          tar -zxvf keepalived-1.3.5.tar.gz

          進(jìn)入解壓縮以后的文件目錄:

          cd keepalived-1.3.5

          編譯安裝:./configure --prefix=/usr/local/keepalived系統(tǒng)提示警告 *** WARNING - this build will not support IPVS with IPv6. Please install libnl/libnl-3 dev libraries to support IPv6 with IPVS.yum -y install libnl libnl-devel再次執(zhí)行./configure --prefix=/usr/local/keepalived系統(tǒng)提示錯誤 configure: error: libnfnetlink headers missingyum install -y libnfnetlink-devel再次執(zhí)行./configure --prefix=/usr/local/keepalived

          make && make install

          到此keepalived安裝完成,但是接下來還有最關(guān)鍵的一步,如果這一步?jīng)]有做后面啟動keepalived的時候會報找不到配置文件的錯誤

          Configuration file '/etc/keepalived/keepalived.conf' is not a regular non-executable file

          安裝完成后,進(jìn)入安裝目錄的etc目錄下,將keepalived相應(yīng)的配置文件拷貝到系統(tǒng)相應(yīng)的目錄當(dāng)中。keepalived啟動時會從/etc/keepalived目錄下查找keepalived.conf配置文件

          mkdir /etc/keepalived

          cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived

          5.2 修改keepalived主節(jié)點(diǎn)192.168.152.130的/etc/keepalived/keepalived.conf配置文件


          5.3 修改keepalived從節(jié)點(diǎn)192.168.152.129的/etc/keepalived/keepalived.conf配置文件

          5.4 檢查nginx是否啟動的shell腳本


          /usr/local/src/check_nginx_pid.sh

          #!/bin/bash
          #檢測nginx是否啟動了
          A=`ps -C nginx --no-header |wc -l`        
          if [ $A -eq 0 ];then    #如果nginx沒有啟動就啟動nginx                        
                /usr/local/nginx/sbin/nginx                #重啟nginx
                if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then    #nginx重啟失敗,則停掉keepalived服務(wù),進(jìn)行VIP轉(zhuǎn)移
                        killall keepalived                    
                fi
          fi


          5.5 192.168.152.130(keepalived主節(jié)點(diǎn))和 192.168.152.129(keepalived從節(jié)點(diǎn))的nginx的配置文件nginx.conf

          user root root; #使用什么用戶啟動NGINX 在運(yùn)行時使用哪個用戶哪個組
          worker_processes 4; #啟動進(jìn)程數(shù),一般是1或8個,根據(jù)你的電腦CPU數(shù),一般8個
          worker_cpu_affinity 00000001 00000010 00000100 00001000; #CPU邏輯數(shù)——把每個進(jìn)程分別綁在CPU上面,為每個進(jìn)程分配一個CPU
          #pid /usr/local/nginx/logs/nginx.pid
          worker_rlimit_nofile 102400; #一個進(jìn)程打開的最大文件數(shù)目,與NGINX并發(fā)連接有關(guān)系
          
          #工作模式及連接數(shù)上限
          events
          {
            use epoll; #多路復(fù)用IO 基于LINUX2.6以上內(nèi)核,可以大大提高NGINX的性能 uname -a查看內(nèi)核版本號
            worker_connections 102400; #單個worker process最大連接數(shù),其中NGINX最大連接數(shù)=連接數(shù)*進(jìn)程數(shù),一般1GB內(nèi)存的機(jī)器上可以打開的最大數(shù)大約是10萬左右
            multi_accept on;   #盡可能多的接受請求,默認(rèn)是關(guān)閉狀態(tài)
          }
          
          #處理http請求的一個應(yīng)用配置段
          http
          {
            #引用mime.types,這個類型定義了很多,當(dāng)web服務(wù)器收到靜態(tài)的資源文件請求時,依據(jù)請求文件的后綴名在服務(wù)器的MIME配置文件中找到對應(yīng)的MIME #Type,根據(jù)MIMETYPE設(shè)置并response響應(yīng)類型(Content-type)
            include       mime.types; 
            default_type  application/octet-stream; #定義的數(shù)據(jù)流,有的時候默認(rèn)類型可以指定為text,這跟我們的網(wǎng)頁發(fā)布還是資源下載是有關(guān)系的
            fastcgi_intercept_errors on; #表示接收fastcgi輸出的http 1.0 response code
            charset utf-8;
            server_names_hash_bucket_size 128; #保存服務(wù)器名字的hash表
            #用來緩存請求頭信息的,容量4K,如果header頭信息請求超過了,nginx會直接返回400錯誤,先根據(jù)client_header_buffer_size配置的值分配一個buffer,如果##分配的buffer無法容納request_line/request_header,那么就會##再次根據(jù)large_client_header_buffers配置的參數(shù)分配large_buffer,如果large_buffer還是無#法容納,那么就會返回414(處理request_line)/400(處理request_header)錯誤。
            client_header_buffer_size 4k; 
            large_client_header_buffers 4 32k;
            client_max_body_size 300m; #允許客戶端請求的最大單文件字節(jié)數(shù) 上傳文件時根據(jù)需求設(shè)置這個參數(shù)
            #指定NGINX是否調(diào)用這個函數(shù)來輸出文件,對于普通的文件我們必須設(shè)置為ON,如果NGINX專門做為一個下載端的話可以關(guān)掉,好處是降低磁盤與網(wǎng)絡(luò)的IO處理數(shù)及#系統(tǒng)的UPTIME
            sendfile on; 
            #autoindex on;開啟目錄列表訪問,適合下載服務(wù)器
            tcp_nopush on; #防止網(wǎng)絡(luò)阻塞
            #非常重要,根據(jù)實(shí)際情況設(shè)置值,超時時間,客戶端到服務(wù)端的連接持續(xù)有效時間,60秒內(nèi)可避免重新建立連接,時間也不能設(shè)太長,太長的話,若請求數(shù)10000##,都占用連接會把服務(wù)托死
            keepalive_timeout 60;
            tcp_nodelay on; #提高數(shù)據(jù)的實(shí)時響應(yīng)性
            client_body_buffer_size 512k; #緩沖區(qū)代理緩沖用戶端請求的最大字節(jié)數(shù)(請求多)
          
            proxy_connect_timeout   5; #nginx跟后端服務(wù)器連接超時時間(代理連接超時)
            proxy_read_timeout      60; #連接成功后,后端服務(wù)器響應(yīng)時間(代理接收超時)
            proxy_send_timeout      5; #后端服務(wù)器數(shù)據(jù)回傳時間(代理發(fā)送超時)
            proxy_buffer_size       16k; #設(shè)置代理服務(wù)器(nginx)保存用戶頭信息的緩沖區(qū)大小
            proxy_buffers           4 64k; #proxy_buffers緩沖區(qū),網(wǎng)頁平均在32k以下的話,這樣設(shè)置
            proxy_busy_buffers_size 128k; #高負(fù)荷下緩沖大小
            proxy_temp_file_write_size 128k; #設(shè)定緩存文件夾大小,大于這個值,將從upstream服務(wù)器傳
          
            gzip on; #NGINX可以壓縮靜態(tài)資源,比如我的靜態(tài)資源有10M,壓縮后只有2M,那么瀏覽器下載的就少了
            gzip_min_length  1k;
            gzip_buffers     4 16k;
            gzip_http_version 1.1;
            gzip_comp_level 2; #壓縮級別大小,最小1,最大9.值越小,壓縮后比例越小,CPU處理更快,為1時,原10M壓縮完后8M,但設(shè)為9時,壓縮完可能只有2M了。一般設(shè)置為2
            gzip_types       text/plain application/x-javascript text/css application/xml; #壓縮類型:text,js css xml 都會被壓縮
            gzip_vary on; #作用是在http響應(yīng)中增加一行目的是改變反向代理服務(wù)器的緩存策略
          
          #日志格式 
          log_format  main '$remote_addr - $remote_user [$time_local] "$request" ' #ip 遠(yuǎn)程用戶 當(dāng)?shù)貢r間  請求URL
                           '$status $body_bytes_sent "$http_referer" ' #狀態(tài)  發(fā)送的大小  響應(yīng)的頭
                   '"$http_user_agent" $request_time'; #客戶端使用的瀏覽器  頁面響應(yīng)的時間
          
          #動態(tài)轉(zhuǎn)發(fā)         
          upstream web1 {
              #每個請求按訪問ip的hash結(jié)果分配,這樣每個訪客固定訪問一個后端服務(wù)器,可以解決session的問題。配置了ip_hash就沒有負(fù)載均衡的效果了,每次訪問的都是同一個tomcat
              #ip_hash; 
              #轉(zhuǎn)發(fā)的后端的tomcat服務(wù)器,weight表示轉(zhuǎn)發(fā)的權(quán)重,越大轉(zhuǎn)發(fā)的次數(shù)越多,機(jī)器性能不一樣配置的weight值不一樣     
               server   192.168.152.129:8080 weight=1 max_fails=2 fail_timeout=30s;
               server   192.168.152.129:8081 weight=1 max_fails=2 fail_timeout=30s;
          }
          upstream web2 {
               server   192.168.152.129:8090 weight=1 max_fails=2 fail_timeout=30s;
               server   192.168.152.129:8091 weight=1 max_fails=2 fail_timeout=30s;
          }
          
          server {
              listen       80; #監(jiān)聽80端口
              server_name  www.dbspread.com; #域名
              #rewrite規(guī)則
              index  index.jsp index.html index.htm;
              root   /usr/local/nginx/html; #定義服務(wù)器的默認(rèn)網(wǎng)站根目錄位置
              #重定向
              if ($host != 'www.dbspread.com' ){ 
                      rewrite ^/(.*)$  http://www.dbspread.com/$1  permanent;
                      }
          
              #防盜鏈
               location ~* \.(rmvb|jpg|png|swf|flv)$ { #rmvb|jpg|png|swf|flv表示對rmvb|jpg|png|swf|flv后綴的文件實(shí)行防盜鏈
                          valid_referers none blocked  www.dbspread.com; #表示對www.dbspread.com此域名開通白名單,比如在www.test.com的index.html引用download/av123.rmvb,無效
                          root   html/b;
                          if ($invalid_referer) { #如果請求不是從www.dbspread.com白名單發(fā)出來的請求,直接重定向到403.html這個頁面或者返回403 
                               #rewrite ^/ http://www.dbspread.com/403.html;
                               return 403;
                          }
                  }
          
              #監(jiān)聽完成以后通過斜桿(/)攔截請求轉(zhuǎn)發(fā)到后端的tomcat服務(wù)器
              location / 
                  {
                      #如果后端的服務(wù)器返回502、504、執(zhí)行超時等錯誤,自動將請求轉(zhuǎn)發(fā)到upstream負(fù)載均衡池中的另一臺服務(wù)器,實(shí)現(xiàn)故障轉(zhuǎn)移。
                      proxy_next_upstream http_502 http_504 error timeout invalid_header;
                      proxy_set_header Host  $host; #獲取客戶端的主機(jī)名存到變量Host里面,從而讓tomcat取到客戶端機(jī)器的信息
                      proxy_set_header X-Real-IP $remote_addr; #獲取客戶端的主機(jī)名存到變量X-Real-IP里面,從而讓tomcat取到客戶端機(jī)器的信息
                      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                      #rewrite     ^/$    http://www.dbspread.com/new.index.html  permanent;#用戶訪問www.dbspread.com,想直接跳轉(zhuǎn)到網(wǎng)站下面的某個頁面:www.dbspread.com/new.index.html
                      proxy_pass http://web1; #跳轉(zhuǎn)到對應(yīng)的應(yīng)用web1
                  }
          
                 # location ~ .*\.(php|jsp|cgi|shtml)?$ #動態(tài)分離 ~匹配 以.*結(jié)尾(以PHP JSP結(jié)尾走這段)
                 #  {
                 #     proxy_set_header Host  $host;
                 #        proxy_set_header X-Real-IP $remote_addr;
                 #        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                 #        proxy_pass http://jvm_web2;
                 # }
          
                  #靜態(tài)分離 ~匹配 以.*結(jié)尾(以html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css結(jié)尾走這段),當(dāng)然不是越久越好,如果有10000個用戶在線,都保存幾個月,系統(tǒng)托跨
                  location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ 
                  {
                      root /var/local/static; #靜態(tài)資源存放在nginx的安裝機(jī)器上
                      #proxy_pass http://www.static.com; #靜態(tài)資源也可存放在遠(yuǎn)程服務(wù)器上
                      expires    30d;
                  }
          
                  #日志級別有[debug|info|notice|warn|error|crit]  error_log 級別分為 debug, info, notice, warn, error, crit  默認(rèn)為crit, 生產(chǎn)環(huán)境用error 
                  #crit 記錄的日志最少,而debug記錄的日志最多
                  access_log  /usr/local/logs/web2/access.log main;
                  error_log   /usr/local/logs/web2/error.log  crit;
          
              }
          
          
          }


          到這一步環(huán)境準(zhǔn)備已完成,相關(guān)的配置也修改完成,下面我們來查看效果


          5.6 配置hosts域名映射


          192.168.152.200  www.dbspread.com

          注意:這里192.168.152.200 是keepalived里面virtual_ipaddress配置的虛擬ip

           virtual_ipaddress {
                  192.168.152.200 # 定義虛擬ip(VIP),可多設(shè),每行一個
              }


          到這一步環(huán)境準(zhǔn)備已完成,相關(guān)的配置也修改完成,下面我們來查看效果


          5.7 分別啟動192.168.152.129的兩個tomcat


          5.8 分別啟動192.168.152.130(keepalived主節(jié)點(diǎn))和

          192.168.152.129(keepalived從節(jié)點(diǎn))的keepalived的

          啟動命令:


          /usr/local/keepalived/sbin/keepalived  

          可以看到keepalived和nginx都啟動了

          在瀏覽器輸入www.dpspread.com域名訪問

          5.9 下面我們停掉主節(jié)點(diǎn)192.168.152.130的keepalived和nginx

          可以看到從節(jié)點(diǎn)變?yōu)橹鞴?jié)點(diǎn)了

          在瀏覽器輸入地址www.dpspread.com訪問,可以看到訪問正常

          5.10 下面我們重新啟動主節(jié)點(diǎn)192.168.152.130

          可以看到主節(jié)點(diǎn)重新啟動以后變?yōu)橹鞴?jié)點(diǎn)了

          之前變?yōu)橹鞴?jié)點(diǎn)的從節(jié)點(diǎn)又變回從節(jié)點(diǎn)了

          到此keepalived+nginx的高可用完美完成

          CSDN 編者按】MySQL之父Monty有著四十多年的編程經(jīng)驗(yàn),從兒時的興趣到長大后的深耕,他在編程領(lǐng)域不斷鉆研,最終成為編程大師。《新程序員004》帶你走進(jìn)Monty的程序人生,談?wù)勊诰幊谭矫娴淖钚赂形蛞约皩ξ磥淼念A(yù)測。

          作者 | 郭露 責(zé)編 | 徐威龍

          出品 | 《新程序員》編輯部

          如今,我們正處于數(shù)據(jù)爆炸的時代,軟件崛起的背后是數(shù)據(jù)的支持。而隨著開源技術(shù)的發(fā)展,越來越多的數(shù)據(jù)庫選擇創(chuàng)建開源社區(qū),讓更多的開發(fā)者參與到數(shù)據(jù)庫的建設(shè)中來。

          在開源數(shù)據(jù)庫領(lǐng)域中,Michael "Monty" Widenius(通常稱為Monty)絕對是不得不提的代表人物。有著四十多年編程經(jīng)驗(yàn)的Monty是MySQL和MariaDB的作者,也是開源軟件運(yùn)動的著名倡導(dǎo)者,即便是現(xiàn)在他也在堅持寫代碼。作為影響了幾代技術(shù)人的數(shù)據(jù)庫,MySQL所取得的成就無需多言。而最初作為MySQL分支立項(xiàng)的MariaDB也在迅速成長,同樣在數(shù)據(jù)庫中贏得了一席之地。

          Monty近照(圖源自Wiki)

          作為在技術(shù)屆游歷半生的資深“程序員”,Monty對編程的理解也有許多獨(dú)到之處,他認(rèn)為只有學(xué)習(xí)編程20年以上,才能像讀懂音樂一樣,看出編程之美。除此之外,他還表示:“寫代碼時要盡量將代碼一次性寫成,而不是寫完后再沒完沒了地修改。”只有做到這一點(diǎn),才能稱得上是一名優(yōu)秀的程序員。而這也是他長久以來所遵循的“編程法則”。

          近期,《新程序員》有機(jī)會邀請Monty分享他的程序人生,談?wù)勊麑τ诩夹g(shù)的感悟,以及對于數(shù)據(jù)庫發(fā)展的看法與心得。

          1.“我在編程方面有一定的天賦”

          1962年,Monty出生在芬蘭首都赫爾辛基,小時候的他便對計算機(jī)有著濃厚的興趣。1978年,年僅16歲的Monty用他一整個暑假打工攢的錢買了人生中的第一臺電腦,并且用BASIC語言寫下了第一行代碼REM,從此以后他便與編程結(jié)下了不解之緣。三年后,Monty被北歐著名高校赫爾辛基理工大學(xué)錄取,但由于自己的學(xué)習(xí)理念與學(xué)校不同,他感到在學(xué)校學(xué)不到什么東西,因此沒過多久就輟學(xué)了。1981年。離開了校園的Monty開始在荷蘭的一家叫做Tapio Laakso Oy的公司當(dāng)程序員。在近十年之后,34歲的Monty開發(fā)出了歷史上最流行的開源數(shù)據(jù)庫之一——MySQL。

          Monty能開發(fā)出MySQL并非偶然,他在編程上投入了大量的時間。根據(jù)早期的資料顯示,就連別人去參加聚會時,他也在家里寫代碼。在他看來,好的代碼不需要一次又一次地重寫,而是在開始寫之前,就抱有一次寫成的心態(tài)。正因?yàn)槿绱耍钡蕉嗄旰蟮慕裉欤琈onty仍然直言“自己在編程方面具有一定的天賦”。

          除了Monty,MySQL的誕生還離不開David Axmark和Allan Larsson。早在1980年,17歲的Monty打算將自己的計算機(jī)內(nèi)存從8KB提高到16KB。機(jī)緣巧合之下,他去往瑞典Allan Larsson的電腦店尋求幫助,在那里認(rèn)識了同樣也是寫代碼的David Axmark,之后三人就成為了親密的合作伙伴,經(jīng)常一起寫代碼,解決編程過程中遇到的問題。1995年,三人創(chuàng)立了MySQL AB,MySQL AB就是MySQL的雛形。這其中Monty負(fù)責(zé)了大部分的開發(fā)工作。最終,在1996年10月,MySQL首個版本發(fā)布,從此掀開了數(shù)據(jù)庫歷史的重要一章。

          到了1999年,MySQL的迅速發(fā)展已經(jīng)引起了許多人的注意, Oracle表示要以5000萬美元的價格收購MySQL。然而Monty三人并不想止步于此,也不想失去對MySQL的控制,因此拒絕了這次收購。

          隨著時間的推移,MySQL迅速發(fā)展, 但同時市場上也出現(xiàn)了包括PostgreSQL在內(nèi)的競爭對手?jǐn)?shù)據(jù)庫。為了在競爭中脫穎而出,MySQL開始接受融資,以獲得更大的發(fā)展機(jī)會。到了2003年,MySQL實(shí)現(xiàn)了高達(dá)400萬的安裝次數(shù),較兩年前翻了一番,成為了當(dāng)時全世界最受歡迎的開源數(shù)據(jù)庫。

          2008年1月16日,Sun Microsystems以高達(dá)10億美元的價格收購MySQL(然而次年Sun又被Oracle收購)。當(dāng)時Monty擔(dān)心MySQL可能會受到Oracle的控制而變得商業(yè)化,并且如果Oracle一家獨(dú)大的話,可能會引發(fā)數(shù)據(jù)庫領(lǐng)域的不良競爭。于是他發(fā)起了一場拯救MySQL的請愿活動,并在MySQL閉源前將其分化,以其小女兒Maria的名字命名創(chuàng)建了MariaDB。

          設(shè)計MariaDB的初衷(圖源自MariaDB官網(wǎng))

          MariaDB開源數(shù)據(jù)庫可以看做是MySQL的一個分支,主要由開源社區(qū)維護(hù),目的是要完全兼容MySQL,甚至包括API和命令行。MariDB推出后,不少M(fèi)ySQL的員工都轉(zhuǎn)而投向MariaDB,甚至是原先使用MySQL的各大公司也將數(shù)據(jù)庫遷移到MariaDB上,其中就包括谷歌和維基百科。Monty表示:“與MySQL相比,MariaDB更加成熟,擁有更大的研發(fā)優(yōu)勢,并且在安全性修復(fù)方面也更加出色。”直到現(xiàn)在,Monty依舊親自參與MariaDB的開發(fā)維護(hù),可以說他的工作重心都在MariaDB上。

          Monty的小女兒Maria(圖源自MariaDB官網(wǎng))

          2.MariaDB,堅持開源的背后

          鄒欣:你在創(chuàng)建MariaDB時,曾提到要把它打造成第二個MySQL,并且確保它是開源的。那么對于數(shù)據(jù)庫而言,為什么開源這么重要呢?

          Monty:對于任何大型項(xiàng)目來說,開源都是非常重要的。既然要和巨頭競爭,你就要有和他們一樣的工具。在我看來,開源很適合用于軟件開發(fā),尤其是當(dāng)公司規(guī)模還不大的時候。這個時候你很難兼顧公司和用戶的需求,因此需要聽取別人的想法。而開源就意味著可以獲得社區(qū)的幫助,能夠了解其他人的觀點(diǎn)。有了開源,你可以開發(fā)出更好的產(chǎn)品,同時產(chǎn)品也能夠獲得更大的影響力。

          鄒欣:不過開源的一大弊端就是聲音太多,需求不一,這種情況下該如何保證數(shù)據(jù)庫能滿足大多數(shù)人的需求呢?

          Monty:要解決這個問題,就需要確保數(shù)據(jù)庫足夠靈活,這樣才能滿足大多數(shù)人的需求。在這一點(diǎn)上,MySQL和MariaDB的做法是建立各種性能不一的存儲引擎,人們可以針對具體需求開發(fā)自己的存儲引擎 。

          事實(shí)上,對于那些有需求的人來說,MariaDB依舊是一個優(yōu)秀的工具。而對于要求數(shù)據(jù)庫體量較小且運(yùn)行較快的人來說,MariaDB同樣是一個不錯的選擇。在開發(fā)MariaDB時,我們考慮到了各種可能性,使它能夠保持良好的性能。

          鄒欣:AI技術(shù)的發(fā)展讓人們對數(shù)據(jù)庫的期待發(fā)生了轉(zhuǎn)變,今天數(shù)據(jù)庫是否能夠與AI技術(shù)結(jié)合,從而擁有數(shù)據(jù)決策能力?

          Monty:對于數(shù)據(jù)庫來說,最重要的是要處理AI需要的不同結(jié)構(gòu)。因此我們添加了對JSON的支持,用于在MariaDB中支持動態(tài)列。這樣人們就可以儲存并檢索數(shù)據(jù),同時保留自己想要的格式。通常AI并不是要創(chuàng)造內(nèi)容,更多的是實(shí)現(xiàn)文件自動化,這就是我們對于MariaDB所抱的期望。因此這兩者完全是不同的工具集。

          除此之外,我們還需要一個良好的環(huán)境,其中每一個部分都是可替代的,要確保自己不被束縛。一旦有了束縛的存在,那么你的應(yīng)用程序就需要與靜態(tài)系統(tǒng)相結(jié)合,這會大大降低靈活性。我認(rèn)為對于數(shù)據(jù)庫來說,要注意的一點(diǎn)就是,要確保數(shù)據(jù)庫容易上手,而這恰恰意味著更多的AI技術(shù)能夠整合到數(shù)據(jù)庫中。

          3.仍然每天堅持寫代碼

          鄒欣:在中國IT行業(yè)有這樣一種現(xiàn)象,認(rèn)為程序員過了35歲就要轉(zhuǎn)型,進(jìn)入管理層或是其他領(lǐng)域。對此你怎么看?

          Monty:這在很多地方都很常見。這個現(xiàn)象的主要原因在于程序員在管理崗位上的工資要比單純做編程高。因?yàn)?strong>很少有公司會重視優(yōu)秀的程序員,這就導(dǎo)致了收入的差異。我認(rèn)為,如今程序員沒有晉升的空間。與其讓他們被迫轉(zhuǎn)型,不如建立一個能提升他們收入的新環(huán)境。要想做到這一點(diǎn),公司就得讓他們承擔(dān)更多的責(zé)任。要程序員擔(dān)任管理崗位也行,但前提是仍然要保證他們每天寫代碼的時間。畢竟好的經(jīng)理人到處都是,好的程序員卻千里挑一。

          鄒欣:據(jù)我所知,你仍然每天在堅持寫代碼,但同時也要負(fù)責(zé)MariaDB的運(yùn)營和管理。那么,你如何平衡這兩個身份呢?

          Monty:我認(rèn)為在寫代碼這方面,我還是有一點(diǎn)天分的,所以我想堅持下去。我會雇用經(jīng)理人為我工作,這樣我就可以做我最擅長的事情。我會參與代碼審查、社區(qū)運(yùn)營以及MariaDB的相關(guān)決策。但同時我也會花很多時間維系客戶,與不同國家的開發(fā)者交流,其中有許多中國的開發(fā)者。我認(rèn)為,除了寫代碼之外,這是我做的最重要的事。總而言之,我會雇傭經(jīng)理人來做一部分管理,讓我有足夠的時間在真正重要的事情上。

          鄒欣:聽聞你從20世紀(jì)80年代就開始在家辦公,如今這一辦公方式也開始流行起來,對于遠(yuǎn)程辦公你有什么看法?

          Monty:事實(shí)上我認(rèn)為遠(yuǎn)程辦公是非常靈活的工作方式,自1981年開始我就在家辦公(MySQL和MariaDB團(tuán)隊都是在家辦公)。我們招人之前可能從來沒見過他們,甚至都不知道對面是個人還是團(tuán)隊。但是我們的效率一直都在線。能做到這一點(diǎn)的前提,是要對跟自己聯(lián)系密切的同事有足夠的了解。至少熟悉他們的樣貌。

          我認(rèn)為對于八成的開發(fā)者而言,在家辦公是一個不錯的選擇。可能有一小部分開發(fā)者,他們的工作負(fù)擔(dān)比較重,在家提不起精神來。這就需要他們出去走走,見見朋友或是接觸新事物。我剛開始在家辦公的時候,也會擔(dān)心這樣是不是會被孤立。所以后來我會定期在家里舉行派對,我也會親自下廚。我們團(tuán)隊每年也會在一起待上一段時間。

          4.一個好的程序員能抵五個一般的程序員

          鄒欣:對于你來說,在過去幾年數(shù)據(jù)庫領(lǐng)域發(fā)生了哪些大的變化?

          Monty:在過去的五年或七年間,學(xué)習(xí)SQL(結(jié)構(gòu)化查詢語言)開始成為一種趨勢。但是人們發(fā)現(xiàn)SQL過于復(fù)雜,因此還需要學(xué)習(xí)其他語言。于是許多公司開始創(chuàng)新,采用NoSQL(非關(guān)系型數(shù)據(jù)庫) 進(jìn)行開發(fā)。但在過去的幾年里,人們逐漸意識到NoSQL并不是萬金油。但選擇關(guān)系型數(shù)據(jù)庫是否能夠涵蓋NoSQL提供的功能?很明顯,有的可以 ,有的不行。因此我認(rèn)為,在當(dāng)下的環(huán)境中,對于數(shù)據(jù)庫的要求在于要保證云端以及本地部署。

          我們不能被一個數(shù)據(jù)庫束縛。云端提供的是靈活性,你能在數(shù)據(jù)庫中運(yùn)行軟件,即使是有成百上千個軟件,而且本地部署的價格更低,控制權(quán)限更高,這一點(diǎn)是云端無法提供的。但我依然認(rèn)為云端有它的優(yōu)勢,我們要在兩者之間找到平衡。

          鄒欣:30年前我從大學(xué)畢業(yè)時,人們提到數(shù)據(jù)庫一般是指去銀行辦業(yè)務(wù)。現(xiàn)在看來,人們有了更多的選擇,我們能夠借助數(shù)據(jù)庫實(shí)現(xiàn)許多功能。但提到數(shù)據(jù)庫開發(fā)時,人們往往指的是“后端”。那么,對于一個開發(fā)者或是畢業(yè)生想要進(jìn)入數(shù)據(jù)庫領(lǐng)域的人來說,你會給他們怎樣的職業(yè)建議?

          Monty:在我看來,從開源數(shù)據(jù)庫開始入門更簡單。現(xiàn)在開源數(shù)據(jù)庫很多,如果你的確想成為專家級別的人,想要得到一份很好的工作,你可以找一個合適的數(shù)據(jù)庫,并學(xué)習(xí)如何進(jìn)行優(yōu)化。但同時你也需要了解人們的需求,你可以和從事這一行的同學(xué)交流,并且學(xué)習(xí)解決數(shù)據(jù)庫中的實(shí)際問題。

          鄒欣:除了多參與開源項(xiàng)目之外,對于中國開發(fā)者你還有哪些想說的?

          Monty:我和來自中國的開發(fā)者有過非常多的互動,他們非常棒,在編程上表現(xiàn)得非常優(yōu)秀。不過我在感到驚喜的同時,也感到非常惋惜,因?yàn)樗麄兌枷朕D(zhuǎn)型做管理。我認(rèn)為這是最大的錯誤。他們需要讓老板給自己派更多的任務(wù),當(dāng)然也可以做管理,但前提是能讓自己寫代碼。還是那句話:找到一個好經(jīng)理很容易,但找到一個好的程序員很難。一個非常出色的程序員可以抵五個一般的程序員,關(guān)鍵是你想當(dāng)一個好的程序員還是一個平庸的經(jīng)理。對于所有中國開發(fā)者,我只想說,請堅持你的工作,你已經(jīng)做得非常好了,一定不要停止寫代碼

          【參考資料】

          https://zh.wikipedia.org/wiki/%E7%B1%B3%E5%8D%A1%E5%9F%83%E7%88%BE%C2%B7%E7%B6%AD%E5%BE%B7%E7%B4%90%E6%96%AF

          https://blog.openocean.vc/founder-stories-a-hackers-hacker-6d5054c90564

          https://huskyintelligence.com/leverage-open-source-code/

          http://monty-says.blogspot.com/2009/12/help-saving-mysql.html

          https://www.geeksforgeeks.org/introduction-of-mariadb/

          http://www.josetteorama.com/from-mysql-to-mariadb-michael-%e2%80%9cmonty%e2%80%9d-widenius-talks-about-databases-and-his-projects/

          https://dri.es/the-history-of-mysql-ab

          https://mariadb.org/wp-content/uploads/2019/11/MySQL-MariaDB-story.pdf


          主站蜘蛛池模板: aⅴ一区二区三区无卡无码| 亚洲Av无码国产一区二区| 又硬又粗又大一区二区三区视频| 国产一区二区视频在线观看| 91一区二区三区四区五区| 另类ts人妖一区二区三区| 国产日韩精品一区二区三区在线 | 国产乱码一区二区三区爽爽爽 | 中文字幕一区二区三区四区 | 日本不卡一区二区三区视频| 美女视频一区二区| 亚洲综合一区二区三区四区五区| 国产成人精品一区在线| 精品人妻一区二区三区四区在线 | 亚洲一区二区三区免费在线观看 | 中文字幕在线看视频一区二区三区 | 高清一区二区三区日本久| 中文字幕无码免费久久9一区9| 文中字幕一区二区三区视频播放 | 国产av福利一区二区三巨| 天美传媒一区二区三区| 亚洲综合一区二区| 国产成人精品一区二区三区免费 | 精品国产福利在线观看一区| 亚洲AV色香蕉一区二区| 国产观看精品一区二区三区| 韩国精品一区二区三区无码视频| 亚洲一区二区三区不卡在线播放| 精品少妇一区二区三区在线| 亚洲片一区二区三区| 色窝窝无码一区二区三区成人网站| 亚洲一区二区三区日本久久九| eeuss鲁片一区二区三区| 日韩一区二区在线免费观看| 国产精品无码一区二区在线观| 久久一区二区三区精华液使用方法| 国产一区二区三区小说| 精品国产日韩一区三区| 韩国女主播一区二区| 无码人妻久久一区二区三区蜜桃| 视频一区在线播放|