本頁說明如何使用 Data API,對 Cloud SQL 執行個體上的資料庫執行 SQL 陳述式。使用 Data API 時,您可以使用 Cloud SQL Admin API 和 gcloud CLI,在已啟用 Data API 存取的任何執行個體上執行 SQL 陳述式。
您可以在使用公開 IP 位址、私人服務存取或 Private Service Connect 的執行個體上使用 Data API。Data API 支援所有類型的 SQL 陳述式,包括資料操縱語言 (DML)、資料定義語言 (DDL) 和資料查詢語言 (DQL)。資料 API 適合執行小型且快速的管理陳述式,例如建立資料庫角色或使用者,以及進行小型結構定義更新。您也可以使用 Data API 啟用 PostgreSQL 擴充功能。
事前準備
您必須先完成下列步驟,才能在執行個體上執行 SQL 陳述式。
設定資料庫使用者
Data API 必須以資料庫使用者的身分通過驗證,才能執行 SQL 陳述式。 您可以透過內建使用者、IAM 使用者、IAM 服務帳戶或 IAM 群組進行驗證。
如要使用 IAM 進行驗證,請按照下列步驟操作:
- 為 IAM 資料庫驗證設定執行個體。
- 在執行個體中新增 IAM 使用者、服務帳戶或群組。
- 授予帳戶執行 SQL 陳述式所需的角色或權限。您可以在建立帳戶或更新帳戶時指派資料庫角色。如果您已建立具備最低權限的自訂資料庫角色,請將這些角色指派給帳戶。否則,請將預先定義的
cloudsqlsuperuser角色指派給帳戶,使用 Data API 建立權限較低的自訂資料庫角色,然後將新角色授予帳戶,取代cloudsqlsuperuser。
如要使用密碼以內建使用者身分進行驗證,請執行下列操作:
- 建立使用者帳戶,並設定密碼。
您也可以使用預設使用者
postgres。 - 授予帳戶執行 SQL 陳述式所需的角色或權限。您可以在建立帳戶或更新帳戶時指派資料庫角色。如果您已建立具備最低權限的自訂資料庫角色,請將這些角色指派給帳戶。否則,請將預先定義的
cloudsqlsuperuser角色指派給帳戶,使用 Data API 建立權限較低的自訂資料庫角色,然後將新角色授予帳戶,取代cloudsqlsuperuser。 - 使用 Secret Manager 建立區域性密鑰來儲存密碼。為確保安全,Data API 會在 API 要求中要求提供密碼的資源名稱,而不是密碼本身。區域密鑰應與 Cloud SQL 執行個體儲存在相同區域。即使是儲存在相同區域,也不支援使用 Secret Manager 的全域端點建立的密鑰。
- 授予 Data API 的呼叫端
roles/secretmanager.secretAccessor。最佳做法是定義 IAM 條件,允許使用者存取特定密鑰,但無法存取專案中的其他密鑰。
必要角色或權限
用於呼叫 Data API 的使用者或服務帳戶必須具備執行 SQL 陳述式 cloudsql.instances.executesql 的權限。下列預先定義的角色都具備這項權限:
Cloud SQL Admin(roles/cloudsql.admin)Cloud SQL Instance User(roles/cloudsql.instanceUser)Cloud SQL Studio User(roles/cloudsql.studioUser)
您也可以為使用者或服務帳戶定義 IAM 自訂角色,其中包含 cloudsql.instances.executesql 權限。這項權限支援身分與存取權管理 (IAM) 自訂角色。
使用 Secret Manager 密鑰進行驗證時,使用者或服務帳戶也必須具備存取密鑰的權限 secretmanager.versions.access。下列預先定義的角色都具備這項權限:
Secret Manager Secret Accessor(roles/secretmanager.secretAccessor)Secret Manager Admin(roles/secretmanager.admin)
啟用或停用 Data API
如要使用 Data API,必須為每個執行個體啟用這項功能。 您隨時可以停用 Data API。
控制台
-
前往 Google Cloud 控制台的「Cloud SQL Instances」頁面。
- 如要開啟執行個體的「總覽」頁面,請按一下執行個體名稱。
- 在 SQL 導覽選單中,選取「連線」。
- 按一下 [網路] 分頁標籤。
- 勾選「允許 Data API」核取方塊。
- 按一下 [儲存]。
gcloud
如要在執行個體上啟用 Google Data API 存取權,請使用 gcloud sql instances patch 指令並加上 --data-api-access=ALLOW_DATA_API 標記:
gcloud sql instances patch INSTANCE_NAME --data-api-access=ALLOW_DATA_API
如要停用 Google Data API 存取權,請使用 --data-api-access=DISALLOW_DATA_API 標記:
gcloud sql instances patch INSTANCE_NAME --data-api-access=DISALLOW_DATA_API
將 INSTANCE_NAME 替換為要啟用或停用 Data API 的執行個體名稱。
REST
如要在執行個體上啟用 Google Data API 存取權,請傳送 PATCH 要求至 instances.patch 端點:
PATCH https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_NAME
要求主體應包含設為 ALLOW_DATA_API 的 dataApiAccess 欄位:
{ "dataApiAccess": "ALLOW_DATA_API" }
如要停用 Data API 存取權,請將 dataApiAccess 設為 DISALLOW_DATA_API。
執行 SQL 陳述式
您可以使用 gcloud CLI 或 REST API,對 Cloud SQL 執行個體上的資料庫執行 SQL 陳述式。
使用 IAM 進行驗證
您可以使用 IAM 資料庫驗證執行 SQL 陳述式。
gcloud
如要使用 gcloud CLI 對執行個體上的資料庫執行 SQL 陳述式,請使用 gcloud sql instances execute-sql 指令。
gcloud sql instances execute-sql INSTANCE_NAME \ --database=DATABASE_NAME \ --sql=SQL_STATEMENT \ --partial-result-mode=PARTIAL_RESULT_MODE
請將下列項目改為對應的值:
- INSTANCE_NAME:執行個體的名稱。
- DATABASE_NAME:執行個體中的資料庫名稱。
- SQL_STATEMENT:要執行的 SQL 陳述式。如果陳述式含有空格或殼層特殊字元,就必須加上引號。
- PARTIAL_RESULT_MODE:選用。控管結果不完整時的回應方式。可以是
ALLOW_PARTIAL_RESULT、FAIL_PARTIAL_RESULT或PARTIAL_RESULT_MODE_UNSPECIFIED。請參閱「修改截斷行為」。
如有需要,您也可以加入 --project=PROJECT_ID 旗標。
Terraform
您可以在 Terraform 上使用 Data API,佈建資料庫內資源,例如資料庫、表格、擴充功能、使用者和權限授予,不必手動連線至執行個體。如要在 Terraform 上執行 SQL 指令碼,請使用
google_sql_provision_script Terraform 資源。
resource "google_sql_database_instance" "instance" { name = "my-instance" database_version = "POSTGRES_17" settings { tier = "db-perf-optimized-N-2" data_api_access = "ALLOW_DATA_API" # This allows the use of Data API. database_flags { name = "cloudsql.iam_authentication" value = "on" } } } /* * Create a database user for your account and grant roles so it has privilege to * access the database. Set the type toCLOUD_IAM_USERfor huamn account or *CLOUD_IAM_SERVICE_ACCOUNTfor service account. If a service account is used * and the instance is Postgres, trim the ".gserviceaccount.com" * suffix to avoid exceeding the username length limit. */ resource "google_sql_user" "iam_user" { name = "account-used-to-apply-this-config@example.com" instance = google_sql_database_instance.instance.name type = "CLOUD_IAM_USER" # Roles granted to the user. For least privilege, you can create smaller roles # and then assign them to this user in place of `cloudsqlsuperuser`. database_roles = ["cloudsqlsuperuser"] } resource "google_sql_database" "database" { name = "my-database" instance = google_sql_database_instance.instance.name } resource "google_sql_provision_script" "script" { # You can inline the script or import from a file likescript = file("${path.module}/script.sql")# When modified, the whole script will be executed again. It's recommended to # make the script idempotent with patterns likecreate if not exists ...or #if not exists (select ...) then ... end if. script = "CREATE TABLE IF NOT EXISTS table1 ( col VARCHAR(16) NOT NULL );" instance = google_sql_database_instance.instance.name database = google_sql_database.database.name description = "sql script to create tables" # The identity account used to apply your Terraform config must exist as an # IAM user or IAM service account in the instance. Terraform connects to the # instance via IAM database authentication to execute the script. depends_on = [google_sql_user.iam_user] }
套用變更
如要在 Google Cloud 專案中套用 Terraform 設定,請完成下列各節的步驟。
準備 Cloud Shell
- 啟動 Cloud Shell。
-
設定要套用 Terraform 設定的預設 Google Cloud 專案 。
每項專案只需要執行一次這個指令,且可以在任何目錄中執行。
export GOOGLE_CLOUD_PROJECT=PROJECT_ID
如果您在 Terraform 設定檔中設定明確值,環境變數就會遭到覆寫。
準備目錄
每個 Terraform 設定檔都必須有自己的目錄 (也稱為根模組)。
-
在 Cloud Shell 中建立目錄,並在該目錄中建立新檔案。檔案名稱的副檔名必須是
.tf,例如main.tf。在本教學課程中,這個檔案稱為main.tf。mkdir DIRECTORY && cd DIRECTORY && touch main.tf
-
如果您正在學習教學課程,可以複製每個章節或步驟中的程式碼範例。
將程式碼範例複製到新建立的
main.tf中。視需要從 GitHub 複製程式碼。如果 Terraform 程式碼片段是端對端解決方案的一部分,建議您使用這個選項。
- 查看並修改範例參數,套用至您的環境。
- 儲存變更。
-
初始化 Terraform。每個目錄只需執行一次這項操作。
terraform init
如要使用最新版 Google 供應商,請加入
-upgrade選項:terraform init -upgrade
套用變更
-
查看設定,確認 Terraform 即將建立或更新的資源符合您的預期:
terraform plan
視需要修正設定。
-
執行下列指令,並在提示中輸入
yes,套用 Terraform 設定:terraform apply
等待 Terraform 顯示「Apply complete!」訊息。
- 開啟 Google Cloud 專案即可查看結果。在 Google Cloud 控制台中,前往 UI 中的資源,確認 Terraform 已建立或更新這些資源。
刪除變更
刪除 google_sql_provision_script 資源不會刪除該資源建立的資料庫內資源。如要刪除這些變數,您可以在指令碼中明確新增 drop ... if exists 等陳述式,然後套用變更。
REST
如要使用 REST API 對執行個體上的資料庫執行 SQL 陳述式,請將 POST 要求傳送至 executeSql 端點:
POST https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_NAME/executeSql
要求主體應包含資料庫名稱和 SQL 陳述式:
{ "database": "DATABASE_NAME", "sqlStatement": "SQL_STATEMENT", "partialResultMode": "PARTIAL_RESULT_MODE" "autoIamAuthn": true }
請將下列項目改為對應的值:
- PROJECT_ID:您的專案 ID。
- INSTANCE_NAME:執行個體的名稱。
- DATABASE_NAME:執行個體中的資料庫名稱。
- SQL_STATEMENT:要執行的 SQL 陳述式。
- PARTIAL_RESULT_MODE:選用。控管結果超過 10 MB 時,API 的回應方式。可以是
FAIL_PARTIAL_RESULT、ALLOW_PARTIAL_RESULT或PARTIAL_RESULT_MODE_UNSPECIFIED。請參閱「修改截斷行為」。
使用密碼驗證
如果密碼以區域密碼的形式儲存在 Secret Manager 中,且與 Cloud SQL 執行個體位於相同區域,您可以使用內建的密碼驗證機制執行 SQL 陳述式。
gcloud
如要使用 gcloud CLI 對執行個體上的資料庫執行 SQL 陳述式,請使用 gcloud sql instances execute-sql 指令。
gcloud sql instances execute-sql INSTANCE_NAME \ --database=DATABASE_NAME \ --sql=SQL_STATEMENT \ --user=USER \ --password-secret-version=PASSWORD_SECRET_VERSION \ --partial-result-mode=PARTIAL_RESULT_MODE
請將下列項目改為對應的值:
- INSTANCE_NAME:執行個體的名稱。
- DATABASE_NAME:執行個體中的資料庫名稱。
- SQL_STATEMENT:要執行的 SQL 陳述式。如果陳述式含有空格或殼層特殊字元,就必須加上引號。
- USER:要驗證身分的資料庫使用者。
- PASSWORD_SECRET_VERSION:Secret Manager Secret 的資源名稱,其中包含資料庫使用者的密碼。密鑰應為區域密鑰,並儲存在與 Cloud SQL 執行個體相同的區域。預期的資源名稱格式為
projects/{project}/locations/{location}/secrets/{secret}/versions/{secret_version}。 - PARTIAL_RESULT_MODE:選用。控管結果不完整時的回應方式。可以是
ALLOW_PARTIAL_RESULT、FAIL_PARTIAL_RESULT或PARTIAL_RESULT_MODE_UNSPECIFIED。請參閱「修改截斷行為」。
Terraform
您可以在 Terraform 上使用 Data API,佈建資料庫內資源,例如資料庫、表格、擴充功能、使用者和權限授予,不必手動連線至執行個體。如要在 Terraform 上執行 SQL 指令碼,請使用
google_sql_provision_script Terraform 資源。
resource "google_sql_user" "built_in_user" { name = "tf-user" host = "%" # Don't set this field for PostgreSQL and SQL Server. instance = google_sql_database_instance.instance.name password = "changeme" type = "BUILT_IN" } # Create a regional secret. Global secrets are not supported even if # located in one region only. resource "google_secret_manager_regional_secret" "secret" { secret_id = "db-password" # Use the same region as the Cloud SQL instance. location = "us-central1" } resource "google_secret_manager_regional_secret_version" "secret_version" { secret = google_secret_manager_regional_secret.secret.id secret_data = "changeme" } resource "google_sql_provision_script" "script" { # You can inline the script or import from a file likescript = file("${path.module}/script.sql")# When modified, the whole script will be executed again. It's recommended to # make the script idempotent with patterns likecreate if not exists ...or #if not exists (select ...) then ... end if. script = "CREATE TABLE IF NOT EXISTS table1 ( col VARCHAR(16) NOT NULL );" instance = google_sql_database_instance.instance.name database = google_sql_database.database.name description = "sql script to create tables" user = google_sql_user.built_in_user.name # The location should be the same as the Cloud SQL instance's location. password_secret_version = "projects/my-project/locations/us-central1/secrets/db-password/versions/latest" # The built-in database user and password secret version must be created # first. Cloud SQL will retrieve password from Secret Manager # and connect to this user account to execute your script. depends_on = [ google_sql_user.built_in_user, google_secret_manager_regional_secret_version.secret_version ] }
套用變更
如要在 Google Cloud 專案中套用 Terraform 設定,請完成下列各節的步驟。
準備 Cloud Shell
- 啟動 Cloud Shell。
-
設定要套用 Terraform 設定的預設 Google Cloud 專案 。
每項專案只需要執行一次這個指令,且可以在任何目錄中執行。
export GOOGLE_CLOUD_PROJECT=PROJECT_ID
如果您在 Terraform 設定檔中設定明確值,環境變數就會遭到覆寫。
準備目錄
每個 Terraform 設定檔都必須有自己的目錄 (也稱為根模組)。
-
在 Cloud Shell 中建立目錄,並在該目錄中建立新檔案。檔案名稱的副檔名必須是
.tf,例如main.tf。在本教學課程中,這個檔案稱為main.tf。mkdir DIRECTORY && cd DIRECTORY && touch main.tf
-
如果您正在學習教學課程,可以複製每個章節或步驟中的程式碼範例。
將程式碼範例複製到新建立的
main.tf中。視需要從 GitHub 複製程式碼。如果 Terraform 程式碼片段是端對端解決方案的一部分,建議您使用這個選項。
- 查看並修改範例參數,套用至您的環境。
- 儲存變更。
-
初始化 Terraform。每個目錄只需執行一次這項操作。
terraform init
如要使用最新版 Google 供應商,請加入
-upgrade選項:terraform init -upgrade
套用變更
-
查看設定,確認 Terraform 即將建立或更新的資源符合您的預期:
terraform plan
視需要修正設定。
-
執行下列指令,並在提示中輸入
yes,套用 Terraform 設定:terraform apply
等待 Terraform 顯示「Apply complete!」訊息。
- 開啟 Google Cloud 專案即可查看結果。在 Google Cloud 控制台中,前往 UI 中的資源,確認 Terraform 已建立或更新這些資源。
刪除變更
刪除 google_sql_provision_script 資源不會刪除該資源建立的資料庫內資源。如要刪除這些變數,您可以在指令碼中明確新增 drop ... if exists 等陳述式,然後套用變更。
REST
如要使用 REST API 對執行個體上的資料庫執行 SQL 陳述式,請將 POST 要求傳送至 executeSql 端點:
POST https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_NAME/executeSql
要求主體應包含資料庫名稱和 SQL 陳述式:
{ "database": "DATABASE_NAME", "sqlStatement": "SQL_STATEMENT", "user": "USER", "passwordSecretVersion": "PASSWORD_SECRET_VERSION", "partialResultMode": "PARTIAL_RESULT_MODE" }
請將下列項目改為對應的值:
- PROJECT_ID:您的專案 ID。
- INSTANCE_NAME:執行個體的名稱。
- DATABASE_NAME:執行個體中的資料庫名稱。
- SQL_STATEMENT:要執行的 SQL 陳述式。
- USER:要驗證身分的資料庫使用者。
- PASSWORD_SECRET_VERSION:Secret Manager Secret 的資源名稱,其中包含資料庫使用者的密碼。密鑰應為區域密鑰,並儲存在與 Cloud SQL 執行個體相同的區域。預期的資源名稱格式為
projects/{project}/locations/{location}/secrets/{secret}/versions/{secret_version}。 - PARTIAL_RESULT_MODE:選用。控管結果超過 10 MB 時,API 的回應方式。可以是
FAIL_PARTIAL_RESULT、ALLOW_PARTIAL_RESULT或PARTIAL_RESULT_MODE_UNSPECIFIED。請參閱「修改截斷行為」。
修改截斷行為
執行 SQL 時,您可以透過在要求中加入 "partialResultMode" 欄位,控管結果大小的處理方式。這個欄位接受下列值:
FAIL_PARTIAL_RESULT:預設值。如果結果超過 10 MB,或只能擷取部分結果,請擲回錯誤。請勿傳回結果。ALLOW_PARTIAL_RESULT:如果結果超過 10 MB,或因發生錯誤而只能擷取部分結果,請傳回截斷的結果,並將partial_result設為 true。請勿擲回錯誤。PARTIAL_RESULT_MODE_UNSPECIFIED:未指定模式,與FAIL_PARTIAL_RESULT相同。
稽核查詢
您可以在要求中設定 applicationName 欄位,追蹤應用程式名稱。資料庫會在工作階段統計資料中追蹤應用程式名稱,例如在下表:
pg_stat_activity。
您可以使用「查詢洞察」追蹤查詢的詳細資訊,並分析效能問題。請注意,查詢洞察會顯示 ExecuteSql 查詢的用戶端 IP 為 localhost,因為資料庫連線是從 Cloud SQL 執行個體內部建立。
您也可以使用 pg-audit 記錄查詢,以確保安全或符合法規。
限制
- 回應大小上限為 10 MB。如果
partialResultMode設為ALLOW_PARTIAL_RESULT,超過這個大小的結果會遭到截斷,否則系統會擲回錯誤。 - 要求大小上限為 0.5 MB。
- 您只能為正在執行的 PostgreSQL 適用的 Cloud SQL 執行個體執行 SQL 陳述式。
- 如果執行個體已設定為外部伺服器複製,Cloud SQL 就不支援搭配使用 Data API。
- 如果要求處理時間超過 30 秒,系統就會取消要求。系統不支援使用
SET STATEMENT_TIMEOUT設定較高的陳述式逾時。 為避免過載,Cloud SQL 會限制每個執行個體的並行
executeSql要求數量。如果達到上限,後續要求就會失敗,並傳回下列其中一個錯誤:At most 'x' concurrent queries may be run on this instance. Try again later.Maximum concurrent reads 'x' reached.
每個執行個體的查詢次數上限 (
x) 為 10 次。每個回應最多可包含 10 則資料庫訊息或警告。
如果陳述式語法或執行階段發生錯誤,系統就不會傳回任何結果。
Data API 無法以密碼為空白的內建使用者身分進行驗證。
如果陳述式耗用大量記憶體,可能會導致記憶體不足錯誤。如要進一步瞭解如何避免這些錯誤,請參閱「管理記憶體用量的最佳做法」。如果資料庫執行個體的記憶體用量偏高,通常會導致效能問題、停滯,甚至資料庫停機。
當執行個體正在進行特定維護作業時,為確保資料完整性,Data API 可能會暫時遭到封鎖。如果發生這種情況,請稍後再試。
- 如果您在查詢編輯器中同時執行多個陳述式,且一或多個陳述式導致錯誤,系統會中止執行所有陳述式,並顯示第一個遇到的錯誤。
- 資料庫伺服器偵測到無效的查詢語法時,會在
postgres.log中產生記錄。這些項目會顯示為cloudsqladmin項目,並包含無效查詢、語法錯誤的位置,以及對應的錯誤訊息。如要從檢視畫面中移除這些記錄,請設定記錄篩選器,排除cloudsqladmin資料庫、cloudsqladmin使用者或兩者。
- SQL 指令碼及其執行回應可能會在用戶端與目標執行個體位置之間的中間位置傳輸。因此,對於特定 Assured Workloads 專案,以及手動強制執行
constraints/sql.restrictNoncompliantResourceCreation的專案,要求會失敗並顯示「not supported for instances in certain Assured Workloads control packages folders」錯誤。
疑難排解
本節提供使用 Data API 時發生的問題,以及問題的疑難排解步驟。
| 問題 | 疑難排解 |
|---|---|
The instance doesn't allow using ExecuteSql to access this instance.
You can allow it by patching the instance with {settings: { dataApiAccess:
"ALLOW_DATA_API" }}
|
Data API 預設為停用。 在執行個體上啟用 Data API,即可解決問題。 |
Secret cannot be provided when auto_iam_authn is true.
|
將 auto_iam_authn 設為 true 時,您會使用 IAM 驗證資料庫。
這個驗證方法不需要密碼或私密金鑰。
請參閱「
使用 IAM 進行驗證」。 |
ExecuteSql API is not supported for instances in certain
Assured Workloads control packages folders yet.
|
SQL 指令碼及其執行回應可能會在用戶端與目標執行個體位置之間的中間位置傳輸。因此,特定 Assured Workloads 專案中的執行個體會導致要求失敗。如果專案未註冊使用 Assured Workloads,但constraints/sql.restrictNoncompliantResourceCreation是
手動強制執行,請要求貴機構的管理員移除限制,新建立的執行個體就會解決問題。
|
IAM authentication is not enabled for the instance
|
為 IAM 驗證設定執行個體,即可解決問題。 |
The database is currently unavailable.
|
執行個體可能正在重新啟動、進行維護,或處於健康狀態不良的狀態。請檢查執行個體狀態,然後稍後再試。 |