

<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>mysql &#8211; Max的程式語言筆記</title>
	<atom:link href="https://stackoverflow.max-everyday.com/tag/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>https://stackoverflow.max-everyday.com</link>
	<description>我要當一個豬頭，快樂過每一天</description>
	<lastBuildDate>Fri, 27 Mar 2026 10:29:06 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://stackoverflow.max-everyday.com/wp-content/uploads/2017/02/max-stackoverflow-256.png</url>
	<title>mysql &#8211; Max的程式語言筆記</title>
	<link>https://stackoverflow.max-everyday.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>MySql 備份登入的帳號與存取 table 的權限</title>
		<link>https://stackoverflow.max-everyday.com/2026/03/mysql-tables_priv/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/03/mysql-tables_priv/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Fri, 27 Mar 2026 08:14:42 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[mysql]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=8160</guid>

					<description><![CDATA[要備份 MySQL 的登入帳號、密碼以及權限（如...]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="559" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2026/03/mysql-tables_priv-1024x559.jpg" alt="" class="wp-image-8164" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2026/03/mysql-tables_priv-1024x559.jpg?v=1774599493 1024w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/03/mysql-tables_priv-600x327.jpg?v=1774599493 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/03/mysql-tables_priv-768x419.jpg?v=1774599493 768w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/03/mysql-tables_priv.jpg?v=1774599493 1408w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>要備份 MySQL 的登入帳號、密碼以及權限（如對 Table 的存取權），最直接的方式是備份系統內建的 <code>mysql</code> 資料庫。這個資料庫專門存儲使用者資訊與權限表（如 <code>user</code>, <code>db</code>, <code>tables_priv</code> 等）。 </p>



<p>以下提供三種主要的備份與匯出方式：</p>



<h2 class="wp-block-heading">1. 使用 mysqldump 備份權限表 (指令列)</h2>



<p>這是最常用的方法，直接將系統權限相關的資料表匯出成 SQL 檔。 [2]</p>



<p><strong>備份所有使用者與權限：</strong></p>



<pre class="wp-block-code"><code>mysqldump -u root -p mysql user db tables_priv columns_priv procs_priv > mysql_privileges.sql</code></pre>



<p><em>這會匯出包含帳號密碼 (user)、資料庫權限 (db) 以及資料表權限 (tables_priv) 的 SQL 檔。</em></p>



<p><strong>備份整個系統資料庫 (最完整)：</strong></p>



<pre class="wp-block-code"><code>mysqldump -u root -p mysql > full_mysql_system_backup.sql</code></pre>



<p>注意：若還原到不同版本的 MySQL，直接覆蓋 mysql 資料庫可能導致相容性問題。</p>



<h2 class="wp-block-heading">2. 匯出權限指令 (推薦用於移機)</h2>



<p>如果你想產出純粹的 <code>CREATE USER</code> 和 <code>GRANT</code> 指令（方便在另一台主機執行），可以使用 <a href="https://dev.mysql.com/doc/refman/9.2/en/mysqldump.html">mysqlpump</a> 特定參數： </p>



<p><strong>使用 mysqldump (最新版支援)：</strong></p>



<pre class="wp-block-code"><code>mysqldump -u root -p --system=users --no-data --no-create-info > user_grants.sql</code></pre>



<p>&#8211;system=users 會將帳號與權限轉換為 GRANT 語法，而非單純的資料表內容。</p>



<h2 class="wp-block-heading">3. 使用 phpMyAdmin (圖形介面)</h2>



<p>適合不習慣指令的使用者： </p>



<ol class="wp-block-list">
<li>登入 <strong>phpMyAdmin</strong>。</li>



<li>在左側面板點選名為 <strong><code>mysql</code></strong> 的資料庫。</li>



<li>勾選 <code>user</code> (帳號)、<code>db</code> (庫權限)、<code>tables_priv</code> (表權限) 等資料表。</li>



<li>點擊上方的 <strong>「匯出」(Export)</strong>，選擇 SQL 格式並執行下載。 </li>
</ol>



<h2 class="wp-block-heading">還原與生效</h2>



<p>還原後，記得在 MySQL 指令列執行以下指令，權限才會立即生效： </p>



<pre class="wp-block-code"><code>FLUSH PRIVILEGES;
</code></pre>



<p><strong>安全提醒：</strong> 備份檔中包含帳號的密碼雜湊值（Hash），請妥善保管此檔案，避免外流。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>還原 MySQL 資料庫的方法主要取決於你手邊有的備份檔案類型。最常見的情況是擁有一個 <code>.sql</code> 格式的備份檔。</p>



<p>以下是三種最常用的還原教學：</p>



<h2 class="wp-block-heading">1. 使用命令列 (Command Line)</h2>



<p>這是最穩定且支援大檔案的方法。請開啟終端機（Linux/Mac）或命令提示字元（Windows），並確保已<a href="https://zeabur.com/zh-TW/templates/DGLGRG">安裝 MySQL 指令列工具</a>。</p>



<p><strong>還原特定資料庫：</strong></p>



<pre class="wp-block-code"><code>mysql -u &#91;帳號] -p &#91;資料庫名稱] &lt; &#91;備份檔路徑].sql </code></pre>



<p>範例：</p>



<pre class="wp-block-code"><code>mysql -u root -p my_database &lt; /path/to/backup.sql</code></pre>



<p><strong>注意事項：</strong> 在執行指令前，請先手動<a href="https://docs.gandi.net/zh-hant/simple_hosting/database_management/mysql.html">建立一個空的資料庫</a>，名稱需與指令中的一致。</p>



<h2 class="wp-block-heading">2. 使用 phpMyAdmin (圖形化網頁介面)</h2>



<p>適合不熟悉指令的使用者，常用於虛擬主機。</p>



<ol class="wp-block-list">
<li>登入 <strong>phpMyAdmin</strong>。</li>



<li>在左側選單中，點選你要還原進去的目標<strong>資料庫</strong>。</li>



<li>點擊頂端選單的<strong>「匯入」 (Import)</strong>。</li>



<li>在「檔案匯入」區塊點選<strong>「選擇檔案」</strong>，挑選你的 <code>.sql</code> 或 <code>.sql.gz</code> 檔案。</li>



<li>捲動到頁面最下方，點擊<strong>「執行」 (Go)</strong>。</li>
</ol>



<h2 class="wp-block-heading">3. 使用 MySQL Workbench (官方工具)</h2>



<p>如果你是開發者並使用電腦上的管理工具：</p>



<ol class="wp-block-list">
<li>開啟 <a href="https://blog.hungwin.com.tw/mysql-workbench-backup/">MySQL Workbench</a> 並連線至資料庫伺服器。</li>



<li>在左側選單點擊 <strong>「Data Import/Restore」</strong>。</li>



<li>選擇 <strong>「Import from Self-Contained File」</strong>，並選取你的備份檔。</li>



<li>在 <strong>「Default Target Schema」</strong> 下拉選單選擇目標資料庫。</li>



<li>點擊右下角的 <strong>「Start Import」</strong> 開始執行。</li>
</ol>



<h2 class="wp-block-heading">常見問題處理</h2>



<ul class="wp-block-list">
<li><strong>檔案過大：</strong> 若使用 phpMyAdmin 匯入大檔案失敗，建議改用「方法 1」指令還原。</li>



<li><strong>外鍵約束錯誤：</strong> 若還原時出現 <code>foreign key constraints</code> 錯誤，有時需要在 SQL 檔開頭暫時停用外鍵檢查。</li>



<li><strong>InnoDB 損毀：</strong> 如果資料庫是因為檔案損毀（如 XAMPP 崩潰），則需要進行 <a href="https://hackmd.io/@m061i6/HyVVvE_Egx">InnoDB 損毀修復</a> 程序。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>要還原整個 MySQL 系統資料庫（包含所有使用者帳號、密碼、權限及全域設定），通常是將之前備份好的 <code>mysql</code> 資料庫 SQL 檔匯入回去。</p>



<p>請注意，<strong>還原系統資料庫具有高風險</strong>，建議在執行前先將目前的 <code>mysql</code> 資料庫備份一份，以防版本不相容導致資料庫無法啟動。</p>



<p>以下是還原步驟：</p>



<h2 class="wp-block-heading">1. 使用命令列還原 (最推薦)</h2>



<p>這是最完整且不會被網頁逾時限制影響的方法。</p>



<p><strong>執行指令：</strong></p>



<pre class="wp-block-code"><code>mysql -u root -p mysql &lt; full_mysql_system_backup.sql </code></pre>



<p>這會將 SQL 內的資料表直接覆蓋回現有的 mysql 系統資料庫中。</p>



<h2 class="wp-block-heading">2. 令權限立即生效</h2>



<p>還原完成後，MySQL 伺服器並不會自動讀取新的權限表，你必須手動登入 MySQL 並執行以下指令：</p>



<pre class="wp-block-code"><code>FLUSH PRIVILEGES;
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 重要注意事項 (必讀)</h2>



<ol class="wp-block-list">
<li><strong>版本相容性：</strong>
<ul class="wp-block-list">
<li><strong>嚴禁</strong>將舊版 MySQL (如 5.7) 的系統資料庫直接還原到新版 (如 8.0)，這會導致伺服器崩潰或無法啟動。</li>



<li>如果是因為升級需求，還原後通常需要執行 <code>mysql_upgrade</code> (在 MySQL 8.0.16 之前的版本) 來修復系統表結構。</li>
</ul>
</li>



<li><strong>連線中斷風險：</strong>
<ul class="wp-block-list">
<li>如果你在還原過程中更改了 <code>root</code> 密碼或權限，還原完成後你當前的連線可能會失效，下次登入請使用「備份檔中」的舊密碼。</li>
</ul>
</li>



<li><strong>僅針對特定使用者還原：</strong>
<ul class="wp-block-list">
<li>如果你只是想在「新主機」上重建帳號，而不打算覆蓋整個系統設定，建議從 SQL 檔中提取 <code>CREATE USER</code> 和 <code>GRANT</code> 語句，而不是還原整個 <code>mysql</code> 資料庫。</li>
</ul>
</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>這是一個非常典型的 <strong>MariaDB/MySQL 恢復衝突</strong>。錯誤訊息 <code>ERROR 1050 (42S01): Table 'user' already exists</code> 意思很直白：資料庫裡已經有一個叫做 <code>user</code> 的資料表了，所以執行 <code>CREATE TABLE</code> 時就撞牆了。</p>



<p>這通常發生在還原 <code>mysql</code> 系統資料庫時，因為 MariaDB 啟動後會自動生成這些系統表。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">為什麼會發生這個問題？</h3>



<p>當你執行 <code>mariadb-dump</code> (或 <code>mysqldump</code>) 時，如果備份指令沒有包含 <code>DROP TABLE</code> 的語句，還原程式就不會主動刪除現有的資料表。而 <code>mysql.user</code> 是系統核心表，它永遠存在於運行中的資料庫中。</p>



<h3 class="wp-block-heading">解決方案</h3>



<h4 class="wp-block-heading">方法一：在還原指令中加入強制覆蓋（推薦）</h4>



<p>如果你目前是手動匯入 SQL 檔，請檢查你的備份檔（dump file）。通常建議在備份時就加上 <code>--add-drop-table</code>，但如果你現在只有這份檔案，可以嘗試在還原指令中加上 <code>-f</code> (force) 參數，強制跳過錯誤繼續執行：</p>



<p>Bash</p>



<pre class="wp-block-code"><code>mariadb -u root -p -f &lt; your_backup_file.sql
</code></pre>



<h4 class="wp-block-heading">方法二：手動修改 SQL 備份檔</h4>



<p>如果你希望還原過程乾淨俐落，可以編輯你的 <code>.sql</code> 檔，在 <code>CREATE TABLE "user"</code> 語句之前，手動加入一行：</p>



<p>SQL</p>



<pre class="wp-block-code"><code>DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` ( ...
</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>注意：</strong> 刪除 <code>mysql.user</code> 表具有高度風險。如果你正在還原的是 <code>mysql</code> 這個系統資料庫，建議先備份目前的 <code>/var/lib/mysql</code> 目錄。</p>
</blockquote>



<h4 class="wp-block-heading">方法三：使用 <code>--replace</code> 或 <code>--insert-ignore</code></h4>



<p>如果你的目的是「更新」權限而非「重建」表結構，且備份檔中包含 <code>INSERT</code> 語句，你可以考慮將 <code>INSERT INTO</code> 改成 <code>REPLACE INTO</code> 或 <code>INSERT IGNORE INTO</code>。不過這需要大範圍修改備份檔，較不建議。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 專業建議：處理系統權限表的正確姿勢</h3>



<p>還原 <code>mysql.user</code> 表後，MariaDB 可能不會立即套用新的權限。<strong>請務必執行以下指令</strong>來刷新權限緩存：</p>



<p>SQL</p>



<pre class="wp-block-code"><code>FLUSH PRIVILEGES;
</code></pre>



<p>此外，如果你是跨版本還原（例如從舊版 MySQL 搬到新版 MariaDB），直接還原 <code>mysql.user</code> 結構可能會導致系統崩潰，因為不同版本的欄位數量和定義不同。在這種情況下，建議：</p>



<ol start="1" class="wp-block-list">
<li>只匯入資料列（Insert）。</li>



<li>匯入後執行 <code>mariadb-upgrade</code> 進行修復。</li>
</ol>



<p><strong>請問您是從舊機器搬移到新機器，還是單純的資料誤刪回滾呢？</strong> 知道情境後我可以提供更精確的步驟。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>這是一個非常關鍵的轉折點。你遇到的 <strong>ERROR 1356</strong> 是因為 <strong>MariaDB 10.x 與 11.x 之間對權限系統進行了重大重構</strong>。</p>



<p>在 MariaDB 10.4 之後（包含你現在用的 11.8），<code>mysql.user</code> 已經不再是一個單純的資料表（Table），而是一個<strong>視圖（View）</strong>。它真正的資料儲存在 <code>mysql.global_priv</code> 之中。</p>



<h3 class="wp-block-heading">為什麼會報錯？</h3>



<p>你正試圖用舊版（10.0）的 <code>CREATE TABLE</code> 語法去覆蓋新版（11.8）的系統架構：</p>



<ol start="1" class="wp-block-list">
<li><strong>結構衝突</strong>：新版的 <code>mysql.user</code> 是 View，你強行用 <code>CREATE TABLE</code> 去還原它，導致資料庫內部邏輯錯亂。</li>



<li><strong>欄位不相容</strong>：10.0 的 <code>user</code> 表有 <code>Password</code> 欄位，而 11.x 使用 JSON 格式儲存在 <code>global_priv</code> 中。</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">正確的還原步驟（針對跨大版本升級）</h3>



<p>在跨越這麼大的版本號（10.0 -&gt; 11.8）時，<strong>絕對不要</strong>直接還原整份 <code>mysql</code> 系統資料庫。請依照以下邏輯操作：</p>



<h4 class="wp-block-heading">1. 只還原業務資料（資料庫）</h4>



<p>先將你的 App 資料還原，跳過系統表：</p>



<p>Bash</p>



<pre class="wp-block-code"><code># 假設你的備份檔叫 backup.sql
# 排除 mysql, information_schema, performance_schema 等系統庫
mariadb -u root -p --force &lt; backup.sql
</code></pre>



<h4 class="wp-block-heading">2. 手動遷移用戶（建議做法）</h4>



<p>由於 <code>mysql.user</code> 的底層結構完全改變，最安全的方法是在 10.0 環境使用工具匯出「帳號權限語句」（GRANT 語法），而非直接匯出資料表。</p>



<p>如果你手邊只有該 SQL 檔，請嘗試搜尋檔案中的 <code>INSERT INTO mysql.user</code> 語句，並手動將其轉化為：</p>



<p>SQL</p>



<pre class="wp-block-code"><code>CREATE USER 'username'@'host' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON db_name.* TO 'username'@'host';
</code></pre>



<h4 class="wp-block-heading">3. 強制執行並修復（高風險但快速）</h4>



<p>如果你必須匯入該系統表，匯入後資料庫可能會無法正常啟動或權限鎖死，此時必須執行修復工具：</p>



<ol start="1" class="wp-block-list">
<li><strong>執行匯入</strong>（加上 <code>-f</code> 強制跳過錯誤）。</li>



<li><strong>執行修復指令</strong>：Bash<code>mariadb-upgrade -u root -p --force </code>這個工具會掃描舊版的系統表，並自動將其轉換為 11.8 所需的格式（例如將 <code>user</code> 表轉換為 <code>global_priv</code> 並重新建立 <code>user</code> View）。</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">總結建議</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><td><strong>版本</strong></td><td><strong>mysql.user 本質</strong></td><td><strong>存儲方式</strong></td></tr></thead><tbody><tr><td><strong>MariaDB 10.0</strong></td><td>實體資料表 (Table)</td><td>傳統欄位 (Password, Select_priv&#8230;)</td></tr><tr><td><strong>MariaDB 11.8</strong></td><td><strong>視圖 (View)</strong></td><td>存儲於 <code>mysql.global_priv</code> (JSON 格式)</td></tr></tbody></table></figure>



<p><strong>最穩妥的方案：</strong></p>



<p>不要還原備份檔中的 <code>mysql</code> 資料庫部分。先還原你的資料（例如 <code>my_app_db</code>），然後在新主機上手動重新 <code>CREATE USER</code>。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>既然您有大量的帳號需要遷移，且從 <strong>MariaDB 10.0</strong> 直接匯入到 <strong>11.8</strong> 會因為底層架構從「實體表」變成「JSON 視圖」而崩潰，最專業且安全的做法是：<strong>從 SQL 備份檔中提取 <code>GRANT</code> 語句，在新環境重新執行。</strong></p>



<p>我為您準備了一個 Bash 腳本，它可以幫您從舊的 <code>.sql</code> 檔案中過濾出建立使用者與權限的語法，避開直接操作系統表（System Tables）。</p>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6e0.png" alt="🛠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 解決方案：提取並遷移權限</h3>



<p>請在您的 Linux 環境下執行以下指令（假設您的備份檔名為 <code>old_backup.sql</code>）：</p>



<p>Bash</p>



<pre class="wp-block-code"><code># 1. 提取所有的 CREATE USER 與 GRANT 語句
grep -E "CREATE USER|GRANT" old_backup.sql &gt; migrate_users.sql

# 2. 檢查一下產出的檔案內容是否正確
cat migrate_users.sql
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 如果您的備份檔只有 <code>INSERT INTO mysql.user</code>&#8230;</h3>



<p>這是最麻煩的情況，因為 10.0 的 <code>INSERT</code> 語法與 11.8 完全不相容。若發生這種情況，請嘗試以下「強制升級法」：</p>



<ol start="1" class="wp-block-list">
<li><strong>先備份目前的環境</strong>（以防萬一）。</li>



<li><strong>強制匯入系統表</strong>：使用 <code>--force</code> 忽略所有 <code>View</code> 或 <code>Table already exists</code> 的錯誤。Bash<code>mariadb -u root -p -f mysql &lt; old_backup.sql</code></li>



<li><strong>關鍵步驟：執行系統升級工具</strong>。這個工具會偵測到您的 <code>mysql.user</code> 格式過舊，並自動將其轉換為 11.8 所需的 <code>global_priv</code> 格式。Bash<code>mariadb-upgrade -u root -p --force</code></li>



<li><strong>重啟服務</strong>：Bash<code>systemctl restart mariadb</code></li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 重要提醒</h3>



<ul class="wp-block-list">
<li><strong>密碼相容性</strong>：MariaDB 11.8 預設可能使用更強的加密外掛（如 <code>ed25519</code>）。如果 10.0 的帳號使用的是舊式的 <code>mysql_native_password</code>，請確保新環境的 <code>my.cnf</code> 設定中允許舊式認證，否則使用者會無法登入。</li>



<li><strong>不要覆蓋 View</strong>：在 11.8 中，<code>mysql.user</code> 是一個方便開發者查看的 <strong>View</strong>。如果您強行用 <code>CREATE TABLE</code> 把他變成實體表，MariaDB 的權限系統會發生不可預期的錯誤。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>在 Windows 環境下，處理 SQL 備份檔的大量文字過濾不像 Linux 那樣可以直接用 <code>grep</code>，但我們可以利用 <strong>PowerShell</strong> 或是 <strong>Notepad++</strong> 來達成同樣的目的。</p>



<p>由於 MariaDB 11.8 將 <code>mysql.user</code> 視為「視圖（View）」，而你的 10.0 備份檔嘗試將其建立為「資料表（Table）」，這就是報錯的主因。</p>



<p>以下是針對 Windows 使用者的三種解決方案：</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">方法一：使用 PowerShell 提取權限語句（推薦）</h3>



<p>如果你想從幾百 MB 甚至 GB 等級的 SQL 檔中只抓出帳號設定，請開啟 PowerShell 並執行：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code># 尋找包含 CREATE USER 或 GRANT 的行，並存到新檔案
Select-String -Path ".\your_backup.sql" -Pattern "CREATE USER|GRANT" | Select-Object -ExpandProperty Line &gt; migrate_users.sql
</code></pre>



<p>執行後，你只需要將產出的 <code>migrate_users.sql</code> 匯入新資料庫即可。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">方法二：手動修正 SQL 檔案（適用於小型備份檔）</h3>



<p>如果你習慣使用編輯器（如 <strong>Notepad++</strong> 或 <strong>VS Code</strong>），請開啟備份檔並搜尋：</p>



<ol start="1" class="wp-block-list">
<li><strong>刪除 <code>CREATE TABLE user</code> 區塊</strong>：從 <code>DROP TABLE IF EXISTS "user";</code> 到 <code>PRIMARY KEY ... ) ENGINE=MyISAM ...;</code> 的這整段程式碼都刪除。</li>



<li><strong>保留 <code>INSERT</code> 語句</strong>：如果你的備份檔是用 <code>INSERT INTO mysql.user</code> 寫入資料，請保留它們，但執行還原時要加上 <code>--force</code>。</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">方法三：Windows 命令列「強制還原 + 修復」</h3>



<p>如果你懶得改檔案，想直接硬衝（這是在 Windows 最常見的做法）：</p>



<ol start="1" class="wp-block-list">
<li><strong>開啟 CMD 或 PowerShell</strong> 並進入 MariaDB 的 <code>bin</code> 目錄（例如 <code>C:\Program Files\MariaDB 11.8\bin</code>）。</li>



<li><strong>強制執行還原</strong>（忽略錯誤繼續跑）：<br><code>mariadb.exe -u root -p --force &lt; "C:\路徑\你的備份檔.sql"</code></li>



<li><strong>執行關鍵修復工具</strong>：這是將 10.0 結構轉換為 11.8 結構的核心步驟。<br><code>mariadb-upgrade.exe -u root -p --force </code><em>這個工具會看到 <code>mysql.user</code> 表格不對勁，自動幫你把它修復成 11.8 規格的 <code>global_priv</code> 並重新建立正確的 View。</em></li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Windows 環境的特別注意事項</h3>



<ul class="wp-block-list">
<li><strong>路徑空格</strong>：如果你的備份路徑有空格（例如 <code>C:\My Backups\db.sql</code>），請務必加上雙引號。</li>



<li><strong>編碼問題</strong>：Windows 預設可能是 <code>UTF-16</code> 或 <code>Big5</code>，但 MariaDB 備份通常是 <code>UTF-8</code>。若執行 PowerShell 提取後出現亂碼，請在指令後加上 <code>-Encoding utf8</code>。</li>



<li><strong>服務重啟</strong>：執行完 <code>mariadb-upgrade</code> 後，建議到「服務 (services.msc)」重啟 MariaDB 服務。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>看到這串錯誤訊息，問題的核心已經非常明確了：</p>



<p>在 <strong>MariaDB 10.11</strong> 中，<code>mysql.user</code> <strong>不再是一個實體資料表，而是一個 View</strong>。你的備份檔（來自 10.0）試圖：</p>



<ol start="1" class="wp-block-list">
<li><code>CREATE TABLE user</code>：這會失敗，因為系統中已經有一個叫 <code>user</code> 的 View（ERROR 1050）。</li>



<li><code>INSERT INTO user</code>：這也會失敗，因為你不能直接對這個特殊的系統 View 執行傳統的 <code>INSERT</code> 語法（ERROR 1356）。</li>
</ol>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6e0.png" alt="🛠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Windows 環境下的最快解決方案</h3>



<p>手動改寫成 <code>CREATE USER</code> 太慢了。請按照以下步驟執行「強制覆蓋與結構修復」：</p>



<h4 class="wp-block-heading">第一步：強制匯入（跳過錯誤）</h4>



<p>打開 <strong>CMD</strong> (命令提示字元)，切換到 MariaDB 的 <code>bin</code> 目錄，執行還原指令並加上 <code>-f</code> (force) 參數。這會讓程式忽略 <code>user</code> 表建立失敗的錯誤，繼續把其他資料還原。</p>



<pre class="wp-block-code"><code>cd /d "C:\Program Files\MariaDB 10.11\bin"
mariadb.exe -u root -p -f &lt; "C:\你的路徑\備份檔.sql"
</code></pre>



<p><em>注意：匯入過程中畫面上會持續出現錯誤訊息，這是正常的，請讓它跑完。</em></p>



<h4 class="wp-block-heading">第二步：執行結構轉換（最關鍵）</h4>



<p>這是修復 <code>mysql.user</code> 的核心動作。<code>mariadb-upgrade</code> 會偵測到你的系統表是 10.0 的舊格式，並自動將那些 <code>INSERT</code> 進去的舊資料轉換成 10.11 所需的 <code>global_priv</code> 格式，並重新生成正確的 <code>user</code> View。</p>



<pre class="wp-block-code"><code>mariadb-upgrade.exe -u root -p --force
</code></pre>



<h4 class="wp-block-heading">第三步：刷新權限與重啟</h4>



<p>在 CMD 中登入 MariaDB 執行刷新：</p>



<pre class="wp-block-code"><code>mariadb -u root -p -e "FLUSH PRIVILEGES;"
</code></pre>



<p>然後去 Windows 的「服務」(<code>services.msc</code>) 重新啟動 <strong>MariaDB</strong> 服務。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 為什麼會有 <code>ERROR 1100 (LOCK TABLES)</code>?</h3>



<p>這是因為備份檔開頭通常有 <code>LOCK TABLES user WRITE;</code>，但因為前面的 <code>CREATE TABLE</code> 失敗了，導致資料庫認為 <code>user</code> 表根本沒被鎖定，後面的 <code>INSERT</code> 和 <code>UNLOCK TABLES</code> 就會連續報錯。<strong>只要執行完上面的 <code>mariadb-upgrade</code>，這些錯誤都會被自動修正。</strong></p>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4dd.png" alt="📝" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 如果 <code>mariadb-upgrade</code> 失敗了怎麼辦？</h3>



<p>如果 upgrade 工具無法修復，代表 10.0 到 10.11 的跨度太大導致結構鎖死。這時你最後的手段是：</p>



<ol start="1" class="wp-block-list">
<li><strong>只還原業務資料庫</strong>：不要還原 <code>mysql</code> 這個資料庫。</li>



<li><strong>手動提取帳號</strong>：如果你需要我幫你寫一段可以在 Windows 跑的 PowerShell 腳本，將你的 <code>INSERT INTO user VALUES (...);</code> 轉換成 <code>CREATE USER</code> 語法，請告訴我，我立刻寫給你。</li>
</ol>



<p><strong>請問您執行完 <code>mariadb-upgrade</code> 後，帳號可以正常登入嗎？</strong></p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/03/mysql-tables_priv/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Python MySQL to MSSQL 資料匯出</title>
		<link>https://stackoverflow.max-everyday.com/2026/03/python-mysql-to-mssql-export/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/03/python-mysql-to-mssql-export/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Mon, 16 Mar 2026 01:58:19 +0000</pubDate>
				<category><![CDATA[Python筆記]]></category>
		<category><![CDATA[mssql]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=7960</guid>

					<description><![CDATA[mysql 使用 mysqldump 產生的 ....]]></description>
										<content:encoded><![CDATA[
<p>mysql 使用 mysqldump 產生的 .sql 檔案, 要匯入到 mssql 之中, 由於匯出的資料量太大, 直接轉換 mysql sql command 為  mssql sql command, 如果使用 SSMS(SQL Server Management Studio) 會遇到記憶體不足的問題.</p>



<p>透過 sqlcmd 匯入資料庫 (不經過 SSMS):</p>



<pre class="wp-block-code"><code>sqlcmd -S localhost -d %db_name% -E -i %output_file%</code></pre>



<p>這個也會遇到很多奇奇怪怪的問題, 明明在 SSMS 執行正常的 table, 在 sqlcmd 會遇到重覆插入 PK 值.</p>



<p>最佳解法是透過下列的python script 進行 export, 這是整合了「逐行讀取」、「自動切分 1000 筆」、「停用約束」以及修正後語法的完整版本：</p>



<pre class="wp-block-code"><code>import re
import pyodbc
import argparse
import sys

def parse_value(val_str):
    """Parse a single SQL value string and return a Python value."""
    val_str = val_str.strip()
    if val_str.upper() == 'NULL':
        return None
    if (val_str.startswith("'") and val_str.endswith("'")):
        # Remove surrounding quotes
        inner = val_str&#91;1:-1]
        # Unescape MySQL-style escape sequences
        result = &#91;]
        i = 0
        while i &lt; len(inner):
            if inner&#91;i] == '\\' and i + 1 &lt; len(inner):
                next_char = inner&#91;i + 1]
                if next_char == "'":
                    result.append("'")
                elif next_char == "\\":
                    result.append("\\")
                elif next_char == "n":
                    result.append("\n")
                elif next_char == "r":
                    result.append("\r")
                elif next_char == "t":
                    result.append("\t")
                elif next_char == "0":
                    result.append("\0")
                elif next_char == "%":
                    result.append("%")
                elif next_char == "_":
                    result.append("_")
                else:
                    result.append(next_char)
                i += 2
            elif inner&#91;i] == "'" and i + 1 &lt; len(inner) and inner&#91;i + 1] == "'":
                # SQL-style escaped quote
                result.append("'")
                i += 2
            else:
                result.append(inner&#91;i])
                i += 1
        return "".join(result)
    # Try numeric
    try:
        if '.' in val_str:
            return float(val_str)
        return int(val_str)
    except ValueError:
        return val_str

def split_row_values(row_str):
    """Split a single row '(val1, val2, ...)' into individual values."""
    # Remove outer parentheses
    inner = row_str.strip()
    if inner.startswith('('):
        inner = inner&#91;1:]
    if inner.endswith(')'):
        inner = inner&#91;:-1]
    
    values = &#91;]
    current = &#91;]
    in_string = False
    i = 0
    
    while i &lt; len(inner):
        char = inner&#91;i]
        
        if in_string:
            if char == '\\' and i + 1 &lt; len(inner):
                current.append(char)
                current.append(inner&#91;i + 1])
                i += 2
                continue
            elif char == "'":
                # Check for escaped quote ''
                if i + 1 &lt; len(inner) and inner&#91;i + 1] == "'":
                    current.append(char)
                    current.append(inner&#91;i + 1])
                    i += 2
                    continue
                else:
                    in_string = False
                    current.append(char)
            else:
                current.append(char)
        else:
            if char == "'":
                in_string = True
                current.append(char)
            elif char == ',':
                values.append("".join(current).strip())
                current = &#91;]
            else:
                current.append(char)
        i += 1
    
    if current:
        values.append("".join(current).strip())
    
    return values

def split_values_robust(values_str):
    """Split VALUES (...),(...),... into individual row strings."""
    rows = &#91;]
    buffer = &#91;]
    paren_depth = 0
    in_string = False
    i = 0
    length = len(values_str)
    
    while i &lt; length:
        char = values_str&#91;i]
        
        if in_string:
            if char == "\\" and i + 1 &lt; length:
                buffer.append(char)
                buffer.append(values_str&#91;i + 1])
                i += 2
                continue
            elif char == "'":
                # Check for '' escape
                if i + 1 &lt; length and values_str&#91;i + 1] == "'":
                    buffer.append(char)
                    buffer.append(values_str&#91;i + 1])
                    i += 2
                    continue
                in_string = False
                buffer.append(char)
            else:
                buffer.append(char)
        else:
            if char == "'":
                in_string = True
                buffer.append(char)
            elif char == "(":
                paren_depth += 1
                buffer.append(char)
            elif char == ")":
                paren_depth -= 1
                buffer.append(char)
                if paren_depth == 0:
                    rows.append("".join(buffer).strip())
                    buffer = &#91;]
            elif char == "," and paren_depth == 0:
                pass
            else:
                if paren_depth > 0:
                    buffer.append(char)
        i += 1
    return rows

def run_import(input_file):
    # 資料庫連線配置
    conn_config = {
        "DRIVER": "{ODBC Driver 18 for SQL Server}",
        "SERVER": "127.0.0.1",
        "DATABASE": "你的資料庫名稱",
        "UID": "帳號",
        "PWD": "密碼",
        "Encrypt": "yes",
        "TrustServerCertificate": "yes"
    }

    conn_str = ";".join(&#91;f"{k}={v}" for k, v in conn_config.items()])

    try:
        conn = pyodbc.connect(conn_str, autocommit=False)
        cursor = conn.cursor()
        print(f"檔案讀取中: {input_file}")
    except Exception as e:
        print(f"連線失敗: {e}")
        return

    try:
        with open(input_file, 'r', encoding='utf-8') as f:
            sql_content = f.read()
    except Exception as e:
        print(f"讀檔失敗: {e}")
        return

    # Handle INSERT INTO with parameterized queries
    insert_pattern = re.compile(
        r"INSERT INTO\s+`?(&#91;\w_]+)`?\s*(?:\((.*?)\))?\s*VALUES\s*(.+?);",
        re.S | re.I
    )

    truncated_tables = set()  # Track tables already truncated
    table_stats = {}  # Track cumulative success/error counts per table

    for match in insert_pattern.finditer(sql_content):
        table_name = match.group(1)
        cols_raw = match.group(2) if match.group(2) else ""
        raw_values = match.group(3)

        # Build column clause
        if cols_raw:
            col_names = &#91;c.strip().replace('`', '') for c in cols_raw.split(',')]
            columns_clause = "(&#91;" + "],&#91;".join(col_names) + "])"
        else:
            # No column list in SQL dump — fetch from MSSQL metadata
            # This is required when IDENTITY_INSERT is ON
            try:
                cursor.execute("""
                    SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
                    WHERE TABLE_NAME = ?
                    ORDER BY ORDINAL_POSITION
                """, table_name)
                db_cols = &#91;row&#91;0] for row in cursor.fetchall()]
                if db_cols:
                    columns_clause = "(&#91;" + "],&#91;".join(db_cols) + "])"
                else:
                    columns_clause = ""
            except:
                columns_clause = ""

        print(f"正在處理: {table_name}")

        # Truncate table before inserting (only once per table)
        if table_name not in truncated_tables:
            try:
                cursor.execute(f"TRUNCATE TABLE &#91;{table_name}]")
                conn.commit()
                print(f"  已清空資料表: {table_name}")
            except Exception as e:
                conn.rollback()
                # TRUNCATE fails if there are foreign key constraints, fallback to DELETE
                try:
                    cursor.execute(f"DELETE FROM &#91;{table_name}]")
                    conn.commit()
                    print(f"  已清空資料表 (DELETE): {table_name}")
                except Exception as e2:
                    conn.rollback()
                    print(f"  清空資料表失敗: {table_name}: {e2}")
            truncated_tables.add(table_name)

        all_rows = split_values_robust(raw_values)
        print(f"  共 {len(all_rows)} 筆資料")

        success_count = 0
        error_count = 0

        # Check if table has IDENTITY column, if so enable IDENTITY_INSERT
        has_identity = False
        try:
            cursor.execute(f"""
                SELECT COUNT(*) FROM sys.identity_columns 
                WHERE OBJECT_NAME(object_id) = ?
            """, table_name)
            row = cursor.fetchone()
            if row and row&#91;0] > 0:
                has_identity = True
        except:
            pass

        if has_identity:
            try:
                cursor.execute(f"SET IDENTITY_INSERT &#91;{table_name}] ON")
            except Exception as e:
                print(f"  無法開啟 IDENTITY_INSERT: {e}")

        for idx, row_str in enumerate(all_rows):
            raw_vals = split_row_values(row_str)
            parsed_vals = &#91;parse_value(v) for v in raw_vals]
            
            placeholders = ",".join(&#91;"?" for _ in parsed_vals])
            sql = f"INSERT INTO &#91;{table_name}] {columns_clause} VALUES ({placeholders})"
            
            try:
                cursor.execute(sql, parsed_vals)
                conn.commit()
                success_count += 1
            except Exception as e:
                conn.rollback()
                error_count += 1
                if error_count &lt;= 3:
                    print(f"  跳過錯誤列 {idx}: {e}")
                    # Print the values for debugging
                    preview_vals = &#91;str(v)&#91;:50] if v is not None else 'NULL' for v in parsed_vals]
                    print(f"  值預覽: {preview_vals}")
                elif error_count == 4:
                    print(f"  (後續錯誤將不再顯示...)")

        if has_identity:
            try:
                cursor.execute(f"SET IDENTITY_INSERT &#91;{table_name}] OFF")
            except:
                pass

        # Accumulate stats per table
        if table_name not in table_stats:
            table_stats&#91;table_name] = {"success": 0, "error": 0}
        table_stats&#91;table_name]&#91;"success"] += success_count
        table_stats&#91;table_name]&#91;"error"] += error_count
        print(f"  本批: 成功 {success_count} 筆, 失敗 {error_count} 筆")

    # Print summary for tables with multiple INSERT batches
    print("\n=== 匯入摘要 ===")
    for tbl, stats in table_stats.items():
        print(f"  {tbl}: 成功 {stats&#91;'success']} 筆, 失敗 {stats&#91;'error']} 筆")

    cursor.close()
    conn.close()
    print("全部完成。")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="MariaDB To MSSQL Migration Tool")
    parser.add_argument("input", help="Path to the .sql dump file")
    args = parser.parse_args()
    
    run_import(args.input)</code></pre>



<p>如果執行過程中遇到記憶體不足的問題，通常是因為 <code>split_values</code> 處理了單一極其巨大的 <code>INSERT</code> 字串。若發生此情況，請告訴我，我們可以改用生成器（Generator）模式來進一步優化字串解析。</p>



<p>上面這個版本針對一般情況是可以使用，針對特定的資料庫欄位類型（例如 Blob 或特殊的日期格式）則需要再進一步的轉換處理。</p>



<p>執行結果:</p>



<figure class="wp-block-image size-full"><img decoding="async" width="528" height="133" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2026/03/mstsc_2026-03-16-09-47-1e.jpg?v=1773626286" alt="" class="wp-image-7961"/></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/03/python-mysql-to-mssql-export/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>移除 MySQL 伺服器的步驟</title>
		<link>https://stackoverflow.max-everyday.com/2026/02/remove-mysql-server/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/02/remove-mysql-server/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Thu, 05 Feb 2026 06:22:48 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=7750</guid>

					<description><![CDATA[移除 MySQL 伺服器的步驟 從 VPS 移除...]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">移除 MySQL 伺服器的步驟</h3>



<p>從 VPS 移除 MySQL 需要根據你的作業系統而定。大多數 VPS 使用 Ubuntu/Debian 或 CentOS/RHEL。請注意，執行這些指令會刪除資料庫軟體，如果你沒有事先備份，資料庫中的資料可能會遺失。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Ubuntu 或 Debian 系統</h3>



<p>這類系統使用 apt 進行套件管理。你需要先停止服務，然後完整移除軟體與設定檔。</p>



<p>停止 MySQL 服務：</p>



<pre class="wp-block-code"><code>sudo systemctl stop mysql</code></pre>



<p>移除所有相關套件：</p>



<pre class="wp-block-code"><code>sudo apt-get purge mysql-server mysql-client mysql-common</code></pre>



<p>清除不需要的依賴套件與快取：</p>



<pre class="wp-block-code"><code>sudo apt-get autoremove
sudo apt-get autoclean</code></pre>



<p>手動刪除殘留的資料夾（包含資料庫檔案）：</p>



<pre class="wp-block-code"><code>sudo rm -rf /etc/mysql /var/lib/mysql /var/log/mysql</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">CentOS 或 RHEL 系統</h3>



<p>這類系統通常使用 yum 或 dnf 進行管理。<sup></sup></p>



<ol start="1" class="wp-block-list">
<li>停止 MySQL 服務：sudo systemctl stop mysqld</li>



<li>移除 MySQL 套件：sudo yum remove mysql mysql-server</li>



<li>檢查是否還有殘留的相關套件：rpm -qa | grep -i mysql（如果有出現結果，請針對該套件名稱執行 yum remove）</li>



<li>刪除資料夾與設定檔：sudo rm -rf /var/lib/mysqlsudo rm /etc/my.cnf</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">檢查是否移除乾淨</h3>



<p>完成上述動作後，你可以嘗試輸入以下指令。如果系統回傳 command not found，代表移除成功：</p>



<pre class="wp-block-code"><code>mysql --version</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">清理防火牆規則</h3>



<p>如果你之前為了遠端連線開啟了 3306 埠，建議也將其關閉。以 ufw 為例：</p>



<pre class="wp-block-code"><code>sudo ufw delete allow 3306/tcp</code></pre>



<p></p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/02/remove-mysql-server/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>MySQL 設定為遠端連入</title>
		<link>https://stackoverflow.max-everyday.com/2026/02/mysql-remote/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/02/mysql-remote/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Thu, 05 Feb 2026 06:17:48 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=7746</guid>

					<description><![CDATA[查詢所有使用者帳號 在 MySQL 中，使用者資...]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">查詢所有使用者帳號</h3>



<p>在 MySQL 中，使用者資訊儲存在 mysql 資料庫的 user 資料表中。你可以執行以下指令來查看系統中所有的帳號以及他們的主機位置：</p>



<p>SELECT user, host FROM mysql.user;</p>



<p>這會列出所有使用者名稱及其對應的連線主機。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">查詢特定使用者的權限</h3>



<p>如果你想查看某個特定使用者的具體權限，可以使用 SHOW GRANTS 指令。語法如下：</p>



<p>SHOW GRANTS FOR &#8216;username&#8217;@&#8217;host&#8217;;</p>



<p>例如，要查詢 root 使用者在本地端的權限：</p>



<p>SHOW GRANTS FOR &#8216;root&#8217;@&#8217;localhost&#8217;;</p>



<p>執行後，系統會回傳一串 GRANT 開頭的指令，這些指令描述了該帳號擁有的所有權限。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">查詢所有使用者的權限清單</h3>



<p>如果你的目標是快速掃描所有使用者的權限，可以直接查詢 mysql.user 表格中的權限欄位。不過這個表格欄位非常多，通常建議只選取幾個關鍵欄位：</p>



<p>SELECT user, host, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv FROM mysql.user;</p>



<p>這能讓你一眼看到哪些帳號具備基本的資料操作權限。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">查詢特定資料庫的權限</h3>



<p>有時候權限是針對特定資料庫設定的，這類資訊儲存在 mysql.db 資料表中。你可以執行：</p>



<p>SELECT user, host, db, Select_priv, Insert_priv FROM mysql.db;</p>



<p>這會顯示哪些使用者對哪些特定的資料庫擁有存取權。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">判斷帳號是否具備遠端連線權限</h3>



<p>在 MySQL 的權限機制中，一個帳號是否能連線取決於 user 表格中的 host 欄位。如果 host 欄位設定為 localhost 或 127.0.0.1，該帳號就只能從資料庫伺服器本機登入。若要從遠端 IP 連線，host 欄位必須是特定的遠端 IP 地址或是萬用字元 %。</p>



<p>你可以執行這行指令來檢查：</p>



<p>SELECT user, host FROM mysql.user WHERE host != &#8216;localhost&#8217; AND host != &#8216;127.0.0.1&#8217;;</p>



<p>如果查詢結果中 host 顯示為 %，代表該帳號可以從任何遠端 IP 位址連線。如果顯示的是特定的 IP 或主機名稱，則代表該帳號僅限從該位置連線。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">檢查 MySQL 監聽狀態</h3>



<p>除了帳號權限外，資料庫本身的網路設定也會影響遠端連線。如果 MySQL 只監聽本機介面，即使帳號 host 設定為 % 也無法連線。你可以檢查系統設定值：</p>



<p>SHOW VARIABLES LIKE &#8216;bind_address&#8217;;</p>



<p>如果結果是 127.0.0.1，代表資料庫只接受本機連線。若要接受遠端連線，這個數值通常會設定為 0.0.0.0。<sup></sup></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">確認權限細節</h3>



<p>有時候帳號雖然可以連線，但沒有進入特定資料庫的權限。你可以針對特定的遠端帳號查看其詳細定義：</p>



<p>SHOW GRANTS FOR &#8216;your_user&#8217;@&#8217;%&#8217;;</p>



<p>這會顯示該遠端帳號具備的所有權限與加密要求。如果 host 設定不是 % 而是特定 IP，請將指令中的 % 替換為該 IP。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">修改 MySQL 設定允許外部 IP 連線</h3>



<p>你的查詢結果顯示 bind_address 為 127.0.0.1，這代表 MySQL 目前被鎖定在只能接受本機連線。即使你修改了使用者權限，遠端連線依然會被系統層級阻擋。你必須先修改設定檔，通常位於 /etc/mysql/mysql.conf.d/mysqld.cnf 或 /etc/my.cnf。</p>



<p>找到 bind-address 這一行，將它改為：</p>



<p>bind-address = 0.0.0.0</p>



<p>這代表允許所有網路介面的連線。修改存檔後，必須重啟 MySQL 服務才會生效：</p>



<p>sudo systemctl restart mysql</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">修改使用者帳號的 Host 屬性</h3>



<p>解決了系統監聽問題後，接著要處理帳號權限。你可以將現有帳號的 host 改為 %（代表任何 IP），或是針對特定 IP 進行設定。最直接的方式是使用 RENAME USER 指令：</p>



<p>RENAME USER &#8216;username&#8217;@&#8217;localhost&#8217; TO &#8216;username&#8217;@&#8217;%&#8217;;</p>



<p>如果你想保留原本的本機帳號，另外建立一個遠端帳號，可以使用 CREATE USER 並賦予權限：</p>



<p>CREATE USER &#8216;username&#8217;@&#8217;%&#8217; IDENTIFIED BY &#8216;your_password&#8217;;</p>



<p>GRANT ALL PRIVILEGES ON database_name.* TO &#8216;username&#8217;@&#8217;%&#8217;;</p>



<p>FLUSH PRIVILEGES;</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">安全性檢查與防火牆設定</h3>



<p>修改完 host 和 bind_address 後，最後一步是確認作業系統的防火牆（如 ufw 或 iptables）是否有開啟 3306 埠。</p>



<p>如果你的伺服器在雲端平台（如 AWS, Google Cloud），還需要在雲端平台的防火牆規則（Security Group）中允許 TCP 3306 埠的入站流量。建議將 % 改為特定的固定 IP，以避免資料庫暴露在公開網路中遭受攻擊。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">使用 mysql 指令連線資料庫</h3>



<p>要在終端機（Terminal）或命令提示字元（CMD）連線到 MySQL 資料庫，最基本的指令格式包含使用者名稱、密碼以及主機位置。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">本機連線方式</h3>



<p>如果你是在安裝資料庫的同一台電腦上連線，可以使用以下指令。輸入後系統會提示你輸入密碼：</p>



<p>mysql -u username -p</p>



<p>如果是要連線後直接進入特定的資料庫，可以在最後加上資料庫名稱：</p>



<p>mysql -u username -p database_name</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">遠端連線方式</h3>



<p>由於你之前檢查過 bind_address 並可能已經開放了遠端存取，連線到遠端伺服器時需要指定主機的 IP 地址或網址：</p>



<p>mysql -h 192.168.1.100 -P 3306 -u username -p</p>



<ul class="wp-block-list">
<li>-h：指定遠端伺服器的 IP 地址。</li>



<li>-P：指定連接埠（預設是 3306，若沒改過可以省略）。</li>



<li>-u：你的使用者名稱。</li>



<li>-p：代表需要密碼（不要直接在 -p 後面寫密碼，這樣會留在指令紀錄中不安全）。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">常見連線參數對照表</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><td><strong>參數</strong></td><td><strong>說明</strong></td><td><strong>範例</strong></td></tr></thead><tbody><tr><td>-h</td><td>主機位址 (Host)</td><td>-h 127.0.0.1</td></tr><tr><td>-u</td><td>使用者名稱 (User)</td><td>-u root</td></tr><tr><td>-p</td><td>密碼 (Password)</td><td>-p</td></tr><tr><td>-P</td><td>連接埠 (Port)</td><td>-P 3306</td></tr><tr><td>-D</td><td>資料庫名稱 (Database)</td><td>-D my_db</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">連線成功後的常用指令</h3>



<p>連線成功後，你會看到 mysql&gt; 的提示字元。這時你可以執行以下指令來確認環境：</p>



<ul class="wp-block-list">
<li>查詢目前所在的資料庫：SELECT DATABASE();</li>



<li>切換資料庫：USE database_name;</li>



<li>列出所有資料庫：SHOW DATABASES;</li>



<li>離開連線：EXIT; 或 QUIT;</li>
</ul>



<p>如果你在連線時遇到時連線失敗（例如 Connection refused），通常是防火牆沒開或是 bind_address 尚未修改生效，需要我幫你排查連線錯誤嗎？</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/02/mysql-remote/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>伺服器資料移轉</title>
		<link>https://stackoverflow.max-everyday.com/2026/02/server-migrate/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/02/server-migrate/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Mon, 02 Feb 2026 12:14:11 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mysql]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=7701</guid>

					<description><![CDATA[要將舊伺服器的資料搬移到新的 VPS，最簡單且穩...]]></description>
										<content:encoded><![CDATA[
<p>要將舊伺服器的資料搬移到新的 VPS，最簡單且穩定的方式是使用 rsync 指令。這個工具可以透過 SSH 安全地傳輸檔案，並且會保留檔案的權限與屬性。</p>



<h3 class="wp-block-heading">準備工作</h3>



<p>在開始搬運之前，請確保你已經把新伺服器的 SSH 公鑰加入到舊伺服器，或者擁有新伺服器的 root 密碼。此外，新舊伺服器之間必須網路互通，因為你提供的是私有 IP (10.130.0.5)，這代表兩台伺服器必須位在同一個 VPS 的 VPC 網路內。</p>



<h3 class="wp-block-heading">執行資料搬移</h3>



<p>請在舊伺服器上執行以下指令，這會將 /root 目錄下的所有內容同步到新伺服器：</p>



<pre class="wp-block-code"><code>rsync -avzP /root/ root@10.130.0.5:/root/
</code></pre>



<p>指令參數解釋：</p>



<ul class="wp-block-list">
<li>-a：代表歸檔模式，會保留連結檔、權限、時間戳記等資訊。</li>



<li>-v：顯示詳細過程。</li>



<li>-z：傳輸時進行壓縮，加快速度。</li>



<li>-P：顯示進度條，如果中斷了可以續傳。</li>
</ul>



<h3 class="wp-block-heading">搬移系統設定檔</h3>



<p>如果你指的 config 包含 /etc 底下的系統設定（例如 Nginx 或資料庫設定），建議針對特定目錄個別搬移，而不是直接覆蓋整個 /etc，因為新舊伺服器的硬體驅動或部分系統組件可能略有不同。</p>



<p>例如搬移 Nginx 設定：</p>



<pre class="wp-block-code"><code>rsync -avzP /etc/nginx/ root@10.130.0.5:/etc/nginx/
</code></pre>



<h3 class="wp-block-heading">資料庫搬移建議</h3>



<p>如果你的 /root 底下包含資料庫原始檔案（例如 MySQL 的 /var/lib/mysql），直接用 rsync 搬移運行中的資料庫檔案可能會導致資料損壞。建議先在舊伺服器執行資料庫匯出（dump），將產出的 .sql 檔放在 /root 內，再執行上述的 rsync 指令，最後到新伺服器匯入。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>這是一個簡單的自動化搬移腳本。這個腳本會先在舊伺服器將資料庫打包（假設使用 MySQL/MariaDB），接著把 /root 目錄與指定的設定目錄同步到新伺服器。</p>



<h3 class="wp-block-heading">自動化搬移腳本</h3>



<p>請在舊伺服器上建立一個名為 migrate.sh 的檔案，並貼入以下內容：</p>



<pre class="wp-block-code"><code>#!/bin/bash
# 設定變數
NEW_SERVER_IP="10.130.0.5"
BACKUP_SQL="/root/all_databases.sql"

echo "正在匯出資料庫..."
mysqldump --all-databases > $BACKUP_SQL

echo "正在傳輸 /root 目錄資料..."
rsync -avzP /root/ root@$NEW_SERVER_IP:/root/

echo "正在傳輸 Nginx 設定 (如果有)..."
if &#91; -d "/etc/nginx" ]; then
    rsync -avzP /etc/nginx/ root@$NEW_SERVER_IP:/etc/nginx/
fi

echo "正在傳輸 SSL 憑證 (LetsEncrypt)..."
if &#91; -d "/etc/letsencrypt" ]; then
    rsync -avzP /etc/letsencrypt/ root@$NEW_SERVER_IP:/etc/letsencrypt/
fi

echo "搬移完成"
</code></pre>



<p>如果要改變 port</p>



<pre class="wp-block-code"><code>#!/bin/bash

# 設定變數
NEW_SERVER_IP="10.130.0.5"
PORT="22"

echo "正在傳輸 /root 目錄資料 (Port: $PORT)..."
rsync -avzP -e "ssh -p $PORT" /root/ root@$NEW_SERVER_IP:/root/</code></pre>



<p></p>



<h3 class="wp-block-heading">修改後的指令碼</h3>



<p>如果你想要在使用 rsync 時排除所有以點號開頭的隱藏檔案或目錄，可以使用 &#8211;exclude 參數並配合通配符。</p>



<pre class="wp-block-code"><code>NEW_SERVER_IP="10.130.0.5"
PORT="22"

echo "正在傳輸 /root 目錄資料 (排除隱藏檔, Port: $PORT)..."
rsync -avzP -e "ssh -p $PORT" --exclude=".*" /root/ root@$NEW_SERVER_IP:/root/</code></pre>



<p></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">參數說明</h3>



<p>在 rsync 中加入 &#8211;exclude=&#8221;.*&#8221; 會讓程式跳過所有名稱開頭為點的檔案與資料夾。這包括常見的設定檔如 .bashrc 或隱藏目錄如 .ssh。</p>



<p>需要注意的是，這個寫法會排除所有層級下的隱藏內容。如果你原本的 /root/ 目錄下有特定的隱藏資料夾是你需要的，則必須改用更具體的排除規則。另外，rsync 預設就不會處理代表目前目錄的 . 與上層目錄的 ..，所以加上這個排除規則不會影響基本的目錄定位。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">搬移自定義 Service 設定檔</h3>



<p>在 Linux 系統中，使用者自定義的 service 設定檔通常放在 <code>/etc/systemd/system/</code> 目錄下。你可以延用之前的 <code>rsync</code> 指令，將這些 <code>.service</code> 檔案同步到新伺服器。</p>



<pre class="wp-block-code"><code>NEW_SERVER_IP="10.130.0.5"
PORT="22"
echo "正在傳輸自定義 service 設定檔 (Port: $PORT)..."
rsync -avzP -e "ssh -p $PORT" /etc/systemd/system/*.service root@$NEW_SERVER_IP:/etc/systemd/system/</code></pre>



<p></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">注意事項與後續步驟</h3>



<p>同步完成後，新伺服器不會自動偵測到這些新檔案，你需要手動執行以下步驟來啟動服務：</p>



<p>重新載入系統設定登入新伺服器，執行以下指令讓系統辨識新加入的 service 檔案：</p>



<pre class="wp-block-code"><code>systemctl daemon-reload</code></pre>



<p>啟用並啟動服務針對你搬移過來的特定服務，執行啟用與啟動指令：</p>



<pre class="wp-block-code"><code>systemctl enable 服務名稱
systemctl start 服務名稱</code></pre>



<h3 class="wp-block-heading">安全建議</h3>



<p>如果你的 service 檔案中包含 <code>ExecStart</code> 指向的路徑（例如 <code>/root/my-app/start.sh</code>），請確保這些執行檔也已經透過之前的指令搬移到新伺服器的相同位置，否則服務將無法順利啟動。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>這是一個自動化腳本片段，你可以將它加入到之前的搬移腳本中。這段程式碼會找出你搬移過去的 service 檔案名稱，並在新伺服器上執行重新載入與啟動的動作。</p>



<h3 class="wp-block-heading">自動化啟動腳本 (新伺服器執行)</h3>



<p>你可以將以下指令存在新伺服器的 <code>setup_services.sh</code> 並執行：</p>



<pre class="wp-block-code"><code>#!/bin/bash

echo "正在重新載入 systemd 設定..."
systemctl daemon-reload

# 取得剛剛搬移過來的自定義 service 列表 (排除系統預設連結)
SERVICES=$(ls /etc/systemd/system/*.service | xargs -n 1 basename)

for SERVICE in $SERVICES; do
    echo "正在啟動並設定服務開機啟動: $SERVICE"
    systemctl enable $SERVICE
    systemctl restart $SERVICE
done

echo "所有自定義服務已嘗試啟動，請執行 systemctl status &#91;服務名] 檢查狀態"
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">遠端一鍵執行 (從舊伺服器觸發)</h3>



<p>如果你希望在舊伺服器同步完檔案後，直接遠端觸發新伺服器載入設定，可以在原本的 <code>rsync</code> 指令後加上這行：</p>



<pre class="wp-block-code"><code>ssh -p $PORT root@$NEW_SERVER_IP "systemctl daemon-reload &amp;&amp; echo '新伺服器已重新載入設定'"</code></pre>



<h3 class="wp-block-heading">貼心提醒</h3>



<p>自定義服務通常會依賴特定的執行環境，請確認以下項目在新伺服器是否已就緒：</p>



<ol start="1" class="wp-block-list">
<li>執行路徑：檢查 .service 檔內的 ExecStart 路徑是否存在。如果路徑是在 /root 底下，請確認你之前的 rsync 已經完整同步該目錄。</li>



<li>軟體環境：如果你的服務是用 Python、Node.js 或 Docker 執行，新伺服器必須先安裝好對應的 runtime。</li>



<li>使用者權限：如果服務設定以特定使用者執行 (User=xxx)，新伺服器必須建立該使用者。</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">執行腳本</h3>



<p>賦予執行權限並執行：</p>



<pre class="wp-block-code"><code>chmod +x migrate.sh
./migrate.sh
</code></pre>



<h3 class="wp-block-heading">後續操作</h3>



<p>當資料傳輸完成後，請登入到新伺服器（10.130.0.5）執行以下步驟來恢復資料庫：</p>



<pre class="wp-block-code"><code>mysql &lt; /root/all_databases.sql
</code></pre>



<p>如果你的服務包含 Nginx 或 Docker，記得在新伺服器安裝對應的軟體後，重啟服務以讀取搬過來的設定檔。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>為了讓新伺服器能承接舊有的服務，你需要安裝與舊伺服器相同的執行環境。以下是一個針對常見網頁環境（Ubuntu/Debian 系統）的自動化安裝腳本，它會安裝 Nginx、MariaDB（MySQL）以及 PHP。</p>



<h3 class="wp-block-heading">環境安裝腳本</h3>



<p>請在新伺服器（10.130.0.5）建立並執行這個腳本：</p>



<pre class="wp-block-code"><code>#!/bin/bash

echo "更新系統軟體源..."
apt update &amp;&amp; apt upgrade -y

echo "安裝基礎工具..."
apt install -y curl wget vim rsync unzip

echo "安裝 Nginx..."
apt install -y nginx

echo "安裝 MariaDB 資料庫..."
apt install -y mariadb-server
systemctl enable mariadb
systemctl start mariadb

echo "安裝 PHP 常用組件..."
apt install -y php-fpm php-mysql php-common php-cli

echo "環境安裝完成"
</code></pre>



<h3 class="wp-block-heading">匯入資料與恢復服務</h3>



<p>在環境安裝好，且你已經執行過舊伺服器的搬移腳本後，請在新伺服器執行以下指令來完成最後的對接：</p>



<p>匯入資料庫：</p>



<pre class="wp-block-code"><code><code>mysql &lt; /root/all_databases.sql</code></code></pre>



<p>檢查 Nginx 設定並重啟：</p>



<pre class="wp-block-code"><code><code>nginx -t &amp;&amp; systemctl restart nginx</code></code></pre>



<h3 class="wp-block-heading">注意事項</h3>



<p>由於新舊伺服器的 IP 不同，如果你的設定檔（如 Nginx 的 config 或網站的 wp-config.php）中有寫死舊伺服器的 IP 位址，記得要搜尋並修改為新伺服器的位址。另外，如果原本有設定防火牆（如 ufw），在新伺服器上也需要重新開啟對應的連接埠（80, 443, 22 等）。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>既然要使用 MySQL，我們需要調整安裝腳本的套件名稱，並在安裝過程中處理可能的權限問題。</p>



<h3 class="wp-block-heading">MySQL 環境安裝腳本</h3>



<p>請在新伺服器（10.130.0.5）執行以下指令：</p>



<pre class="wp-block-code"><code>#!/bin/bash

echo "更新系統軟體源..."
apt update

echo "安裝 MySQL Server..."
# 設定非互動模式，避免安裝過程跳出視窗要求輸入密碼
export DEBIAN_FRONTEND=noninteractive
apt install -y mysql-server

echo "啟動並設定 MySQL 開機自啟..."
systemctl start mysql
systemctl enable mysql

echo "安裝 Nginx 與 PHP 組件..."
apt install -y nginx php-fpm php-mysql

echo "MySQL 環境安裝完成"
</code></pre>



<h3 class="wp-block-heading">匯入資料庫的注意事項</h3>



<p>在執行 mysql &lt; /root/all_databases.sql 之前，由於 MySQL 8.0 以上版本的 root 帳號預設使用 auth_socket 認證，你可能需要使用 sudo 權限才能順利匯入：</p>



<pre class="wp-block-code"><code>sudo mysql &lt; /root/all_databases.sql
</code></pre>



<h3 class="wp-block-heading">調整舊 IP 關鍵字</h3>



<p>如果你擔心舊的設定檔（例如 Nginx config）裡還留著舊伺服器的 IP，可以在新伺服器的 /etc 目錄執行這行指令，將所有舊 IP 批次替換成新的（請將 1.2.3.4 替換為你的舊伺服器公網或私網 IP）：</p>



<pre class="wp-block-code"><code>grep -rl "1.2.3.4" /etc/nginx | xargs sed -i 's/1.2.3.4/10.130.0.5/g'</code></pre>



<p>最後記得重啟服務讓設定生效：</p>



<pre class="wp-block-code"><code>systemctl restart nginx
systemctl restart mysql</code></pre>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/02/server-migrate/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>要找出 Server 空間被誰佔用</title>
		<link>https://stackoverflow.max-everyday.com/2026/01/server-du-mysql-binlog/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/01/server-du-mysql-binlog/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Mon, 26 Jan 2026 18:02:53 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=7681</guid>

					<description><![CDATA[要找出 VPS 空間被誰佔用，我們需要從根目錄開...]]></description>
										<content:encoded><![CDATA[
<p>要找出 VPS 空間被誰佔用，我們需要從根目錄開始層層往下追蹤。你的硬碟總共 25G，目前已使用 17G，這對許多純文字服務的 VPS 來說確實偏高。</p>



<h3 class="wp-block-heading">找出佔用空間的目錄</h3>



<p>首先使用 du 指令來查看根目錄下各個資料夾的大小。這行指令會列出總量並由大到小排序，讓我們一眼看出兇手在哪：</p>



<p>Bash</p>



<pre class="wp-block-code"><code>sudo du -h --max-depth=1 / 2&gt;/dev/null | sort -hr
</code></pre>



<p>通常佔用空間的常見原因有以下幾種：</p>



<h3 class="wp-block-heading">系統日誌與快取</h3>



<p>很多時候是日誌檔（Logs）累積太久沒有清理。你可以檢查 /var/log 資料夾。如果發現 journal 佔用太多，可以用這條指令限制日誌大小：</p>



<p>Bash</p>



<pre class="wp-block-code"><code>sudo journalctl --vacuum-size=500M
</code></pre>



<p>另外，如果你使用 Ubuntu 或 Debian，套件管理器的快取也可能堆積在 /var/cache/apt/archives。執行以下指令可以清除：</p>



<p>Bash</p>



<pre class="wp-block-code"><code>sudo apt-get clean
</code></pre>



<h3 class="wp-block-heading">Docker 容器與鏡像</h3>



<p>如果你有安裝 Docker，過期的鏡像（Images）和停止的容器（Containers）非常佔空間。你可以透過這個指令直接清除所有沒在使用的 Docker 資源：</p>



<p>Bash</p>



<pre class="wp-block-code"><code>docker system prune -a
</code></pre>



<h3 class="wp-block-heading">隱藏在刪除程序中的檔案</h3>



<p>有一種情況是檔案已經刪除了，但空間沒釋放。這是因為某個程序還在讀取該檔案。你可以用這條指令找出這些「幽靈檔案」：</p>



<p>Bash</p>



<pre class="wp-block-code"><code>sudo lsof / | grep deleted
</code></pre>



<p>如果看到很大的檔案被列出，重啟該服務或是直接重新開機就能討回空間。</p>



<p>你想先從哪個目錄查起，或是需要我幫你分析特定目錄的內容嗎？</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<pre class="wp-block-preformatted">➜  ~ sudo du -h --max-depth=1 / 2>/dev/null | sort -hr<br>17G     /<br>9.5G    /var<br>6.0G    /usr<br>713M    /boot<br>216M    /root<br>159M    /home<br>6.9M    /etc<br>976K    /run<br>56K     /tmp<br>16K     /lost+found<br>4.0K    /Users<br>4.0K    /srv<br>4.0K    /opt<br>4.0K    /mnt<br>4.0K    /media<br>0       /sys<br>0       /proc<br>0       /dev</pre>



<p>從你的查詢結果來看，最大宗的佔用集中在 /var (9.5G) 和 /usr (6.0G)。</p>



<h3 class="wp-block-heading">追蹤 /var 目錄</h3>



<p>/var 通常存放的是會變動的資料。最常見的兇手是日誌檔、套件快取或資料庫。請執行以下指令來縮小範圍：</p>



<p>Bash</p>



<pre class="wp-block-code"><code>sudo du -h --max-depth=1 /var 2&gt;/dev/null | sort -hr
</code></pre>



<p>如果 /var/log 很大，通常是系統日誌堆積；如果 /var/lib 很大，則可能是 Docker 容器或是資料庫（如 MySQL）的數據庫檔案。</p>



<h3 class="wp-block-heading">追蹤 /usr 目錄</h3>



<p>/usr 佔用了 6.0G，這主要是系統安裝的軟體和函式庫。雖然 6G 對於現代 Linux 來說還在合理範圍，但如果你的 VPS 只有跑簡單服務，這可能代表裝了太多沒用的套件。你可以檢查看看是哪個子目錄最胖：</p>



<p>Bash</p>



<pre class="wp-block-code"><code>sudo du -h --max-depth=1 /usr 2&gt;/dev/null | sort -hr
</code></pre>



<h3 class="wp-block-heading">關於 /boot 的提醒</h3>



<p>雖然 /boot 只佔了 713M，但對於某些 VPS 預設的磁碟分割來說，這可能會造成更新時空間不足。這通常是舊版的 Linux 核心（Kernel）堆積造成的。</p>



<p>你可以先執行 /var 的查詢指令，把結果貼出來，我們直接針對大頭進行清理嗎？</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<pre class="wp-block-preformatted">➜  ~ sudo du -h --max-depth=1 /var 2>/dev/null | sort -hr<br>9.5G    /var<br>9.3G    /var/lib<br>140M    /var/log<br>9.2M    /var/cache<br>632K    /var/backups<br>36K     /var/tmp<br>32K     /var/www<br>28K     /var/crash<br>16K     /var/spool<br>4.0K    /var/opt<br>4.0K    /var/mail<br>4.0K    /var/local</pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>兇手已經抓到了，就是 /var/lib 這個目錄，它佔用了高達 9.3G。</p>



<p>在 Linux 中，/var/lib 是用來存放應用程式運行時狀態資料的地方。最常佔用這個位置的通常是 Docker 或資料庫檔案。</p>



<h3 class="wp-block-heading">繼續深入定位</h3>



<p>請執行以下指令，看看 /var/lib 裡面到底是哪個程式佔用了空間：</p>



<p>Bash</p>



<pre class="wp-block-code"><code>sudo du -h --max-depth=1 /var/lib 2&gt;/dev/null | sort -hr
</code></pre>



<h3 class="wp-block-heading">常見的情況預測</h3>



<ol start="1" class="wp-block-list">
<li>如果是 /var/lib/docker：這代表 Docker 的鏡像檔（Images）、容器層或是卷軸（Volumes）堆積太多。你可以先用 <code>docker system df</code> 確認 Docker 的空間使用狀況。</li>



<li>如果是 /var/lib/mysql 或 /var/lib/postgresql：這代表你的資料庫資料量很大，或者是日誌檔（如 binlog）沒清理。</li>



<li>如果是 /var/lib/snapd：代表你使用 Snap 安裝了許多套件，它會保留舊版本的檔案。</li>
</ol>



<p>你可以跑一下上面的指令，把前幾名列出來看看嗎？</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<pre class="wp-block-preformatted">➜  ~ sudo du -h --max-depth=1 /var/lib 2>/dev/null | sort -hr<br>9.3G    /var/lib<br>8.9G    /var/lib/mysql<br>273M    /var/lib/apt<br>91M     /var/lib/mecab<br>52M     /var/lib/dpkg<br>6.2M    /var/lib/ubuntu-advantage<br>3.4M    /var/lib/command-not-found<br>704K    /var/lib/usbutils<br>556K    /var/lib/systemd<br>316K    /var/lib/fwupd<br>124K    /var/lib/ucf<br>40K     /var/lib/polkit-1<br>36K     /var/lib/PackageKit<br>28K     /var/lib/pam<br>24K     /var/lib/nginx<br>20K     /var/lib/update-notifier<br>16K     /var/lib/grub<br>12K     /var/lib/update-manager<br>8.0K    /var/lib/vim<br>8.0K    /var/lib/ubuntu-release-upgrader<br>8.0K    /var/lib/sudo<br>8.0K    /var/lib/logrotate<br>8.0K    /var/lib/landscape<br>8.0K    /var/lib/cloud<br>8.0K    /var/lib/apport<br>4.0K    /var/lib/usb_modeswitch<br>4.0K    /var/lib/upower<br>4.0K    /var/lib/unattended-upgrades<br>4.0K    /var/lib/udisks2<br>4.0K    /var/lib/tpm<br>4.0K    /var/lib/python<br>4.0K    /var/lib/private<br>4.0K    /var/lib/plymouth<br>4.0K    /var/lib/os-prober<br>4.0K    /var/lib/mysql-upgrade<br>4.0K    /var/lib/mysql-keyring<br>4.0K    /var/lib/mysql-files<br>4.0K    /var/lib/misc<br>4.0K    /var/lib/man-db<br>4.0K    /var/lib/git<br>4.0K    /var/lib/fail2ban<br>4.0K    /var/lib/dhcp<br>4.0K    /var/lib/dbus<br>4.0K    /var/lib/boltd</pre>



<p>結果非常明顯，佔用空間的元兇是 /var/lib/mysql，它獨自佔用了 8.9G。這代表你的 MySQL 資料庫存放了大量的數據，或者是產生了過多的日誌檔案。</p>



<h3 class="wp-block-heading">檢查 MySQL 內部佔用</h3>



<p>通常資料庫變大有兩個原因：一個是你的資料表真的很肥，另一個是開啟了 Binary Log（二進位日誌），這會記錄所有對資料庫的更動，主要用於備援與同步，但非常吃空間。</p>



<p>你可以進到該目錄看看有哪些大檔案：</p>



<p>Bash</p>



<pre class="wp-block-code"><code>sudo ls -lh /var/lib/mysql | sort -k 5 -rh | head -n 10
</code></pre>



<h3 class="wp-block-heading">常見的清理方向</h3>



<p>如果看到很多檔名類似 binlog.0000X 的檔案，那可以透過以下方式清理：</p>



<ol start="1" class="wp-block-list">
<li>登入 MySQL：<code>sudo mysql -u root -p</code></li>



<li>執行指令清理過舊的日誌（例如保留最近 3 天）：<code>PURGE BINARY LOGS BEFORE NOW() - INTERVAL 3 DAY;</code></li>



<li>或者是直接限制日誌保留的天數，修改 /etc/mysql/my.cnf 裡面的 <code>binlog_expire_logs_seconds</code> 設定。</li>
</ol>



<h3 class="wp-block-heading">檢查特定的資料庫</h3>



<p>如果你想知道是哪個資料庫（Database）或資料表（Table）最胖，可以登入 MySQL 後執行這段 SQL：</p>



<p>SQL</p>



<pre class="wp-block-code"><code>SELECT table_schema AS "Database", 
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS "Size (MB)" 
FROM information_schema.TABLES 
GROUP BY table_schema;
</code></pre>



<p>這能幫你確認是哪個專案的資料量異常。</p>



<p>需要我幫你看看 ls -lh 的結果，來判斷是數據檔還是日誌檔造成的嗎？</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<pre class="wp-block-preformatted">➜  ~ sudo ls -lh /var/lib/mysql | sort -k 5 -rh | head -n 10<br>-rw-r----- 1 mysql mysql 101M Jan  9 19:40 binlog.000032<br>-rw-r----- 1 mysql mysql 101M Jan  9 12:41 binlog.000031<br>-rw-r----- 1 mysql mysql 101M Jan  9 06:00 binlog.000030<br>-rw-r----- 1 mysql mysql 101M Jan  8 20:21 binlog.000028<br>-rw-r----- 1 mysql mysql 101M Jan  8 13:01 binlog.000027<br>-rw-r----- 1 mysql mysql 101M Jan  8 06:27 binlog.000026<br>-rw-r----- 1 mysql mysql 101M Jan  7 19:42 binlog.000024<br>-rw-r----- 1 mysql mysql 101M Jan  7 12:41 binlog.000023<br>-rw-r----- 1 mysql mysql 101M Jan  7 06:00 binlog.000022<br>-rw-r----- 1 mysql mysql 101M Jan  6 20:21 binlog.000020</pre>



<p>從結果來看，你的 MySQL 產生了大量的 binlog（二進位日誌）。雖然單個檔案只有 101M，但數量顯然非常驚人，這就是吃掉你 8.9G 空間的主要原因。</p>



<h3 class="wp-block-heading">解決方案：清理 binlog</h3>



<p>這些檔案記錄了資料庫的所有更動，如果你沒有做資料庫主從同步（Replication）的需求，可以安全地清理它們。</p>



<p>請先登入 MySQL：</p>



<p>Bash</p>



<pre class="wp-block-code"><code>sudo mysql -u root -p
</code></pre>



<p>進入後執行以下指令，只保留最近 1 天的日誌（這會立即釋放大量空間）：</p>



<p>SQL</p>



<pre class="wp-block-code"><code>PURGE BINARY LOGS BEFORE NOW() - INTERVAL 1 DAY;
</code></pre>



<p>如果你完全不需要這些日誌，也可以直接刪除所有舊日誌，只保留目前正在使用的一個：</p>



<p>SQL</p>



<pre class="wp-block-code"><code>RESET MASTER;
</code></pre>



<h3 class="wp-block-heading">預防措施：限制日誌保留天數</h3>



<p>為了避免之後空間又被塞滿，建議修改 MySQL 設定檔。請編輯 <code>/etc/mysql/mysql.conf.d/mysqld.cnf</code>（或是 <code>/etc/mysql/my.cnf</code>）：</p>



<p>使用指令:</p>



<pre class="wp-block-code"><code>vi /etc/mysql/mysql.conf.d/mysqld.cnf</code></pre>



<ol start="1" class="wp-block-list">
<li>找到 <br><code>binlog_expire_logs_seconds</code> <br>或 <br><code>expire_logs_days</code>（舊版）。</li>



<li>設定較短的過期時間。例如保留 3 天（$3 \times 24 \times 3600 = 259200$ 秒）：<br><code>binlog_expire_logs_seconds = 259200</code><br>(預設值是 2592000)</li>



<li>儲存後重啟 MySQL：<br><code>sudo systemctl restart mysql</code></li>
</ol>



<p>執行完 <code>PURGE</code> 或 <code>RESET MASTER</code> 後，你可以再次執行 <code>df -h</code> 看看，空間應該會釋放好幾個 G。需要我幫你確認目前的設定檔位置嗎？</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/01/server-du-mysql-binlog/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>mysql join table twice</title>
		<link>https://stackoverflow.max-everyday.com/2023/11/mysql-join-table-twice/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/11/mysql-join-table-twice/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Wed, 08 Nov 2023 04:31:39 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[mysql]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=5156</guid>

					<description><![CDATA[如何在 mysql 的 select 裡 joi...]]></description>
										<content:encoded><![CDATA[
<p>如何在 mysql 的 select 裡 join 同一個 table 2 次, 答案是使用 as alias 即可.</p>



<p>為什麼會有這個需求? 以 user_id 為例, 有可能有2個欄位都是儲存 user_id, 但是是不同帳號的 user_id, 希望在 select 的 join 之後, 可以顯示出這2個不同的  user_id 欄位裡的 usre_name.</p>



<pre class="wp-block-code"><code>SELECT toD.dom_url AS ToURL, 
    fromD.dom_url AS FromUrl, 
    rvw.*

FROM reviews AS rvw

LEFT JOIN domain AS toD 
    ON toD.Dom_ID = rvw.rev_dom_for

LEFT JOIN domain AS fromD 
    ON fromD.Dom_ID = rvw.rev_dom_from
</code></pre>



<p>you can use&nbsp;<a href="https://www.w3schools.com/SQL/sql_alias.asp">Alias</a></p>



<p>資料來源:<br><a href="https://stackoverflow.com/questions/50007406/mysql-left-join-same-table-twice-with-same-field">https://stackoverflow.com/questions/50007406/mysql-left-join-same-table-twice-with-same-field</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/11/mysql-join-table-twice/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>mysql select not in list</title>
		<link>https://stackoverflow.max-everyday.com/2023/10/mysql-select-not-in-list/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/10/mysql-select-not-in-list/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Fri, 27 Oct 2023 08:42:26 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[mysql]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=5096</guid>

					<description><![CDATA[在 MSSQL 的世界, 直接用 in 或 no...]]></description>
										<content:encoded><![CDATA[
<p>在 MSSQL 的世界, 直接用 in 或 not in () 很方便, 但 mysql 沒有這個功能, 替代方案是把 2個 table left join 起來, 取出 null 的就是 not in.</p>



<p>解法: </p>



<p>If you don&#8217;t want to (explicitly) use temporary tables, this will work:</p>



<pre class="wp-block-code"><code>SELECT tmp_table.id
FROM tmp_table
LEFT JOIN users u ON tmp_table.id = u.id
WHERE u.id IS NULL;</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Demo</h2>



<p>Create the temporary table:</p>



<pre class="wp-block-code"><code>CREATE TABLE a_table (id INT);
CREATE TABLE b_table (id INT);</code></pre>



<p>Insert values:</p>



<pre class="wp-block-code"><code>INSERT INTO a_table (id) values (1),(2),(3),(4),(5);
INSERT INTO b_table (id) values (1),(3),(5);</code></pre>



<p>Check A not in B, should select 2,4:</p>



<pre class="wp-block-code"><code>select a_table.id
from a_table
left join b_table on a_table.id = b_table.id
where b_table.id is null;</code></pre>



<figure class="wp-block-image size-full"><img decoding="async" width="646" height="351" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/10/2023-10-27-16_55_32-Window.jpg" alt="" class="wp-image-5100" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/10/2023-10-27-16_55_32-Window.jpg?v=1698397132 646w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/10/2023-10-27-16_55_32-Window-600x326.jpg?v=1698397132 600w" sizes="(max-width: 646px) 100vw, 646px" /></figure>



<p></p>



<p>相直接刪掉這些不同步的資料, 在 MS SQL 很簡單, 但在 MYSQL 很麻煩，下面的語法會顯示錯誤:</p>



<pre class="wp-block-code"><code>delete from a_table
left join b_table on a_table.id = b_table.id
where b_table.id is null;</code></pre>



<p>修改成這樣，也是錯：</p>



<pre class="wp-block-code"><code>DELETE a_table.*
FROM a_table
WHERE a_table.id IN (SELECT id
             FROM (SELECT a_table.id from a_table
left join b_table on a_table.id = b_table.id
where b_table.id is null));</code></pre>



<p>但是，非常神奇的是，加了一個 x 一切就OK了, 什麼鬼, 太難理解!</p>



<pre class="wp-block-code"><code>DELETE a_table.*
FROM a_table
WHERE a_table.id IN (SELECT id
             FROM (SELECT a_table.id from a_table
left join b_table on a_table.id = b_table.id
where b_table.id is null) x);</code></pre>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="889" height="464" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/10/2023-10-27-17_10_28-Window.jpg" alt="" class="wp-image-5101" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/10/2023-10-27-17_10_28-Window.jpg?v=1698397851 889w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/10/2023-10-27-17_10_28-Window-600x313.jpg?v=1698397851 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/10/2023-10-27-17_10_28-Window-768x401.jpg?v=1698397851 768w" sizes="auto, (max-width: 889px) 100vw, 889px" /></figure>



<p></p>



<p>最後, 刪掉測試用 table:</p>



<pre class="wp-block-code"><code>drop table a_table;<br>drop table b_table;</code></pre>



<p>附註: 在測試沒驗證過的 sql command 前, 請先備份 database, 以免重要資料在非預期的狀態下被 delete command 刪掉&#8230;。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">資料來源</h2>



<p>SELECT that returns list of values not occurring in any row<br><a href="https://stackoverflow.com/questions/10013475/select-that-returns-list-of-values-not-occurring-in-any-row">https://stackoverflow.com/questions/10013475/select-that-returns-list-of-values-not-occurring-in-any-row</a></p>



<p>Query to Check for Values Not Matching List in Where Clause<br><a href="https://stackoverflow.com/questions/72218215/query-to-check-for-values-not-matching-list-in-where-clause">https://stackoverflow.com/questions/72218215/query-to-check-for-values-not-matching-list-in-where-clause</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/10/mysql-select-not-in-list/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How To Allow Remote Access to MySQ</title>
		<link>https://stackoverflow.max-everyday.com/2023/07/how-to-allow-remote-access-to-mysq/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/07/how-to-allow-remote-access-to-mysq/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Wed, 12 Jul 2023 06:42:07 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[mysql]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=4930</guid>

					<description><![CDATA[由於資安的需求, 資料庫不能與運行的主程式放同一...]]></description>
										<content:encoded><![CDATA[
<p>由於資安的需求, 資料庫不能與運行的主程式放同一台, 所以要把mysql 搬出來, 就需要設定允許 mysql 可以遠端連進去. </p>



<p>open up your&nbsp;<code>mysqld.cnf</code>&nbsp;file:</p>



<pre class="wp-block-code"><code>sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="694" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/07/2023-07-12-11_00_17-Window-1024x694.jpg?v=1689130941" alt="" class="wp-image-4931" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/07/2023-07-12-11_00_17-Window-1024x694.jpg?v=1689130941 1024w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/07/2023-07-12-11_00_17-Window-600x407.jpg?v=1689130941 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/07/2023-07-12-11_00_17-Window-768x520.jpg?v=1689130941 768w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/07/2023-07-12-11_00_17-Window.jpg?v=1689130941 1222w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>修改</p>



<pre class="wp-block-code"><code>bind-address = 127.0.0.1</code></pre>



<p>為</p>



<pre class="wp-block-code"><code>bind-address = 0.0.0.0</code></pre>



<p>重啟 server</p>



<pre class="wp-block-code"><code>sudo systemctl restart mysql</code></pre>



<p>照下面的格式, 建立使用者:</p>



<pre class="wp-block-code"><code>CREATE USER 'your-account'@'remote_server_ip' IDENTIFIED BY 'account-password';</code></pre>



<p>給權限:</p>



<pre class="wp-block-code"><code>GRANT CREATE, INDEX, ALTER, DROP, INSERT, UPDATE, DELETE, SELECT, REFERENCES on database_name.* TO 'your-account'@'remote_server_ip' WITH GRANT OPTION;

FLUSH PRIVILEGES;</code></pre>



<p>附註：如果這個帳號，沒有權限可以使用create index 的話，請把 INDEX 這個項目刪除。 </p>



<p>檢查用的 script:</p>



<pre class="wp-block-code"><code>SELECT user,host FROM mysql.user;</code></pre>



<p>如果有必要的話, 要啟用防火牆規則:</p>



<p>If you only plan to access the database server from one specific machine, you can grant that machine exclusive permission to connect to the database remotely with the following command. Make sure to replace&nbsp;<code><mark>remote_IP_address</mark></code>&nbsp;with the actual IP address of the machine you plan to connect with:</p>



<pre class="wp-block-code"><code>sudo ufw allow from <mark>remote_IP_address</mark> to any port 3306</code></pre>



<p>如果要允許, 所有的電腦都可以連到 3306 port: (被攻擊的風險較高)</p>



<pre class="wp-block-code"><code>sudo ufw allow 3306</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/07/how-to-allow-remote-access-to-mysq/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>mysql Error Code: 1064. You have an error in your SQL syntax;</title>
		<link>https://stackoverflow.max-everyday.com/2023/05/mysql-error-code-1064-you-have-an-error-in-your-sql-syntax/</link>
					<comments>https://stackoverflow.max-everyday.com/2023/05/mysql-error-code-1064-you-have-an-error-in-your-sql-syntax/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Mon, 29 May 2023 07:30:40 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[mysql]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=4858</guid>

					<description><![CDATA[在 mysql 裡遇到一個錯誤訊息: Error...]]></description>
										<content:encoded><![CDATA[
<p>在 mysql 裡遇到一個錯誤訊息:</p>



<pre class="wp-block-preformatted">Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '05152018_bwamem.sam' where id=6' at line 1
</pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="528" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/05/2023-05-29-14_55_03-Window-1024x528.jpg?v=1685343560" alt="" class="wp-image-4859" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2023/05/2023-05-29-14_55_03-Window-1024x528.jpg?v=1685343560 1024w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/05/2023-05-29-14_55_03-Window-600x309.jpg?v=1685343560 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/05/2023-05-29-14_55_03-Window-768x396.jpg?v=1685343560 768w, https://stackoverflow.max-everyday.com/wp-content/uploads/2023/05/2023-05-29-14_55_03-Window.jpg?v=1685343560 1178w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p></p>



<p>遇到的 sql command:</p>



<pre class="wp-block-code"><code>update component set code='bwa  mem -t 4 -R ''@RG\ILLUMINA\''  05152018_bwamem.sam' where id=6;</code></pre>



<p>發生的原因, \ (backslash) 在 mysql 是跳脫字元, 愈多跳脫, 就愈多問題!</p>



<p>解法:</p>



<p>Mysql 的 NO_BACKSLASH_ESCAPES<br><a href="https://stackoverflow.max-everyday.com/2017/08/mysql-no_backslash_escapes/">https://stackoverflow.max-everyday.com/2017/08/mysql-no_backslash_escapes/</a></p>



<p>修改檔案的 /etc/my.cnf.d/mysql-server.cnf</p>



<pre class="wp-block-code"><code>
&#91;mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysql/mysqld.log
pid-file=/run/mysqld/mysqld.pid

sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION,NO_BACKSLASH_ESCAPES</code></pre>



<p>說明: 就只有增加 sql_mode= 這行指令. 並重啟 mysql server:</p>



<pre class="wp-block-code"><code>sudo service mysqld restart</code></pre>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2023/05/mysql-error-code-1064-you-have-an-error-in-your-sql-syntax/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
