發表文章

目前顯示的是 1月, 2021的文章

[Linux] SSH Tunnel

前情提要 由於中華電信最近除了海底纜線斷掉之外,連內部路由都有問題,造成部分用戶的 socket 會連不到我們架設的伺服器,於是想到把自建的 socket server 從機房中複製一份到 GCP 上面。 但由於安全性的問題,資料庫是在機房內網,且沒有對外 IP,還有 redis 也是在機房內網,同樣沒有對外 IP,這時候該怎麼辦? 厲害同事介紹了一招,SSH Tunnel。 SSH Tunnel 單純就是幫忙做 Port Forwarding。 假設我現在我有台主機 A,需要連線到內網的資料庫,但只有主機 B 才可以直接透過內網連線到資料庫,則我們可以透過 SSH Tunnel 將內網資料庫的 3306 port,對應到主機 A 的自定義 port,流量則是透過主機 B 轉給內網的資料庫。 定義一下名詞: 主機 A => socket server 主機 B => ap 資料庫 => db 1. 先在 db 內開一個專門用來 ssh 的帳號,假設叫 tunneluser 2. 在 db 開的 tunneruser 的 ~/.ssh/authorized_keys 內新增 socket server 的 public key 3. 在 ap 內開一個專門用來 ssh 的帳號,假設叫 tunneluser 4. 在 ap 開的 tunneruser 的 ~/.ssh/authorized_keys 內新增 socket server 的 public key 5. 接下來在 socket server 上的 ~/.ssh/config內新增 Host ap HostName 1.2.3.4 User tunneluser Port 22 IdentityFile ~/.ssh/id_rsa Host db HostName 2.2.3.4 Port 22 User tunneluser ProxyCommand ssh -q -W %h:%p ap IdentityFile ~/.ssh/id_rsa 6. 接著在 socket server 中輸入 nohup ssh -N -L 3306:localhost:3306 db & nohup 跟後面的 & 是為了把 ssh tunnel 放在背景持續執行 第一個 3306 是 so

[MySQL] 8.0 replica

最近剛好需要幫公司的資料庫做 replica, 但由於之前的資料庫沒有開啟 binlog, 所以研究了一下該怎麼操作。 如果是剛開始建立服務,建議 binlog 的設定要記得打開,如果沒有打開的話,變成要實作 replica 就需要先將資料備份出來,然後在備份出來的 master 資料還原給 slave,之後再去開啟 master 的 binlog,與建立要給 slave 同步用的帳號。 稍微解釋一下主從式架構,主要是由 master 來執行讀與寫,然後每個操作會記錄在 binlog 中,master 會透過 REPLICATION 這個權限讓 slave 可以去取回 binlog 的操作,藉由非同步的方式同步資料。 預先提醒,如果 slave 是由 master 透過複製虛擬機出來的,如果遇到 Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs;  these UUIDs must be different for replication to work 這個錯誤,就是代表 MySQL Server 的 UUID 重複,這時候只需要把 slave 的 /var/lib/mysql/auto.cnf 這個檔案刪除,之後執行 service mysql restart 就可以解決問題囉! Master 1. 以 Ubuntu 20.10 為例,MySQL 設定 replica 的設定檔在 /etc/mysql/mysql.conf.d/mysqld.cnf 在該檔案中加入 binlog_do_db = 指定的資料庫 bind-address = 0.0.0.0 server_id = 1 log_bin = /var/lib/mysql/mysql-bin.log log-slave-updates = 0 expire_logs_days = 10 # 如果開始 sync_binlog = 1 與innodb_flush_log_at_trx_commit # 一致性會是最好,但會影響效能。 sync_binlog = 0 innodb_flush_log_at_trx_commit = 0 # in

[MySQL] schema 與資料類型優化

圖片
選擇優化的資料類型 原則: 越小越好 因為會佔用最小的磁碟、記憶體與CPU快取。 越簡單越好 操作整數比操作字串代價低,因為字串排序規則 ex: 儲存ip應該用 unsigned int - 4 bytes, 用 varchar 會用到 15 bytes 儲存時間應該用 mysql 內建的時間類型 DATETIME, TIMESTAMP可以儲存相同資料:時間日期,精確到秒 TIMESTAMP 只用 DATETIME 一半的儲存空間,根據時區自動變化 TIMESTAMP 允許的時間範圍比 DATETIME 小很多 避免 NULL 在 innodb 上有單獨的 bit 儲存 null 值,但在 myisam,但還是盡量避免 整數類型 tinyint - 8 bits smallint - 16 bits mediumint - 24 bits int - 32 bits bigint - 64 bits 如果是有正負數的,會因為 1 bits 會用來記錄正負,故範圍為 -2^(n-1) ~ 2^(n-1) unsigned 的範圍則是 -2^n ~ 2^n MySQL 可以為整數指定寬度,例如 INT(11),其實沒什麼意義,11只是表示與 MySQL 相關工具(client 端的 cli) 用來顯示的長度,對於儲存與計算來說,INT(1)與INT(20)是一樣的。 實數類型 decimal(M,N) - M: 最大位數, N: 小數點後有幾位 ex: decimal(18, 9) => 9位數字.9位數字,總共使用 9 個 bytes float => 4 bytes double => 8 bytes decimal的計算雖然比較精確,但需要額外,但需要額外的空間與計算開銷,資料量較大時,可以用 bigint 代替 decimal,假設需要精準到萬分之一,則可以將數字*1百萬,將結果存在 bigint 內,可以同時避免福點數計算不精準與 decimal 計算代價太高。 字串類型 VARCHAR row_format=fix,這樣就都會固定長度,沒意義 varchar會需要額外1~2 bytes記錄長度, 假設用 latin1 charset, varchar(10) => 11 bytes, varchar(1000) => 1002