從 Amazon Aurora MySQL 資料庫叢集叫用 Lambda 函式 - Amazon Aurora

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

從 Amazon Aurora MySQL 資料庫叢集叫用 Lambda 函式

您可以使用原生 AWS Lambda 函數或從 Amazon Aurora 與 MySQL 相容的版本資料庫叢集叫用函數。lambda_sync lambda_asyncAurora 資料庫叢集必須能夠存取 Lambda,您才能從 Aurora MySQL 叫用 Lambda 函式。如需有關授予 Aurora MySQL 存取權的詳細資訊,請參閱授權 Aurora 存取 Lambda。如需 lambda_synclambda_async 預存函數的相關資訊,請參閱使用 Aurora MySQL 原生函式叫用 Lambda 函式

您也可以使用預存程序呼叫 AWS Lambda 函式。不過,已棄用預存程序。如果您使用下列其中一個 Aurora MySQL 版本,強烈建議使用 Aurora MySQL 原生函數:

  • Aurora MySQL 第 2 版,適用於 MySQL 5.7 相容的叢集。

  • Aurora MySQL 3.01 版和更新版本,適用於 MySQL 8.0 相容的叢集。預存程序不適用於 Aurora MySQL 第 3 版。

授權 Aurora 存取 Lambda

在可以從 Aurora MySQL 資料庫叢集叫用 Lambda 函式之前,務必首先授權您的叢集存取 Lambda,。

授權 Aurora MySQL 存取 Lambda
  1. 建立一個 AWS Identity and Access Management (IAM) 政策,以提供允許您的 Aurora MySQL 資料庫叢集叫用 Lambda 函數的許可。如需說明,請參閱「建立 IAM 政策來存取 AWS Lambda 資源」。

  2. 建立 IAM 角色,並將您於建立 IAM 政策來存取 AWS Lambda 資源中建立的 IAM 政策連接至新的 IAM 角色。如需說明,請參閱「建立 IAM 角色以允許 Amazon Aurora 存取 AWS 服務」。

  3. aws_default_lambda_role 資料庫叢集參數設為新的 IAM 角色的 Amazon Resource Name (ARN)。

    如果叢集屬於 Aurora 全球資料庫,請對全球資料庫中的每個 Aurora 叢集套用相同的設定。

    如需資料庫叢集參數的詳細資訊,請參閱 Amazon Aurora 資料庫叢集和資料庫執行個體參數

  4. 若要允許 Aurora MySQL 資料庫叢集的資料庫使用者叫用 Lambda 函式,請將您在建立 IAM 角色以允許 Amazon Aurora 存取 AWS 服務中建立的角色與資料庫叢集建立關聯。如需將 IAM 角色與資料庫叢集建立關聯的相關資訊,請參閱將 IAM 角色與 Amazon Aurora MySQL 資料庫叢集建立關聯

    如果叢集屬於 Aurora 全球資料庫,請將此角色與全球資料庫中的每個 Aurora 叢集建立關聯。

  5. 設定 Aurora MySQL 資料庫叢集來允許對外連接至 Lambda。如需說明,請參閱「啟用從 Amazon Aurora MySQL 至其他 AWS 服務的網路通訊」。

    如果叢集屬於 Aurora 全球資料庫,請對全球資料庫中的每個 Aurora 叢集啟用傳出連線。

使用 Aurora MySQL 原生函式叫用 Lambda 函式

注意

使用 Aurora MySQL 第 2 版,或 Aurora MySQL 3.01 版和更新版本時,您可以呼叫原生函數 lambda_synclambda_async。如需 Aurora MySQL 版本的詳細資訊,請參閱 Amazon Aurora MySQL 的資料庫引擎更新

您可以呼叫原生 AWS Lambda 函數lambda_synclambda_async. 當您想要將 Aurora MySQL 上執行的資料庫與其他 AWS 服務整合時,此方法非常有用。例如,每當資料庫的特定資料表中插入一列時,您可能想要使用 Amazon Simple Notification Service (Amazon SNS) 傳送通知。

使用原生函數呼叫 Lambda 函數

lambda_synclambda_async 函式是內建的原生函式,可同步或非同步叫用 Lambda 函式。如果您在繼續執行另一個動作之前,必須得知 lambda_sync 函數的結果,請使用同步函數 Lambda。如果您在繼續執行另一個動作之前,並不需要得知 Lambda 函數的結果,請使用非同步函數 lambda_async

在 Aurora MySQL 第 3 版中授予角色

在 Aurora MySQL 第 3 版中,必須將 AWS_LAMBDA_ACCESS 角色授予叫用原生函數的使用者。若要將此角色授予使用者,請以管理使用者身分連接至資料庫執行個體,然後執行下列陳述式。

GRANT AWS_LAMBDA_ACCESS TO user@domain-or-ip-address

您可以執行下列陳述式來撤銷此角色。

REVOKE AWS_LAMBDA_ACCESS FROM user@domain-or-ip-address
提示

在 Aurora MySQL 第 3 版中使用角色技術時,您也可以使用 SET ROLE role_nameSET ROLE ALL 陳述式啟用角色。如果您不熟悉 MySQL 8.0 角色系統,您可以在角色型權限模型進一步了解。有關更多詳細信息,請參閱 MySQL 參考手冊中的使用角色

此僅適用於目前的作用中工作階段。重新連線時,您必須再次執行SET ROLE陳述式以授與權限。如需詳細資訊,請參閱 MySQL Reference Manual (MySQL 參考手冊) 中的 SET ROLE 陳述式

您可以使用 activate_all_roles_on_login 資料庫叢集參數,在使用者連線至資料庫執行個體時自動啟動所有角色。設定此參數時,通常不需要明確呼叫SET ROLE陳述式即可啟用角色。如需詳細資訊,請參閱 MySQL Reference Manual (MySQL 參考手冊) 中的 activate_all_roles_on_login

不過,當不同的使用者呼叫預存程序時,您必須在預存程序開頭SET ROLE ALL明確呼叫,才能啟動角色。

如果在嘗試叫用 Lambda 函數時出現如下錯誤,請執行 SET ROLE 陳述式。

SQL Error [1227] [42000]: Access denied; you need (at least one of) the Invoke Lambda privilege(s) for this operation

在 Aurora MySQL 第 2 版中授予權限

在 Aurora MySQL 第 2 版中,必須將 INVOKE LAMBDA 權限授予叫用原生函數的使用者。若要將此權限授予使用者,請以管理使用者身分連接至資料庫執行個體,然後執行下列陳述式。

GRANT INVOKE LAMBDA ON *.* TO user@domain-or-ip-address

您可以執行下列陳述式來撤銷此權限。

REVOKE INVOKE LAMBDA ON *.* FROM user@domain-or-ip-address

lambda_sync 函數的語法

您可以指定 lambda_sync 呼叫類型,以同步呼叫 RequestResponse 函數。此函數會在 JSON 承載中傳回 Lambda 呼叫結果。此函數的語法如下。

lambda_sync ( lambda_function_ARN, JSON_payload )

lambda_sync 函數的參數

lambda_sync 函數具有下列參數。

lambda_function_ARN

要呼叫之 Lambda 函數的 Amazon Resource Name (ARN)。

JSON_payload

所呼叫之 Lambda 函數的承載 (JSON 格式)。

注意

Aurora MySQL 第 3 版支援來自 MySQL 8.0 的 JSON 解析函數。不過,Aurora MySQL 第 2 版不包含這些函數。當 Lambda 函數傳回最小單位值時,例如數字或字串,就不需要 JSON 剖析。

lambda_sync 函數範例

下列以 lambda_sync 為基礎的查詢使用函式 ARN,以同步叫用 Lambda 函式 BasicTestLambda。函數的承載為 {"operation": "ping"}

SELECT lambda_sync( 'arn:aws:lambda:us-east-1:123456789012:function:BasicTestLambda', '{"operation": "ping"}');

lambda_async 函數的語法

您可以指定 lambda_async 呼叫類型,以非同步呼叫 Event 函數。此函數會在 JSON 承載中傳回 Lambda 呼叫結果。此函數的語法如下。

lambda_async ( lambda_function_ARN, JSON_payload )

lambda_async 函數的參數

lambda_async 函數具有下列參數。

lambda_function_ARN

要呼叫之 Lambda 函數的 Amazon Resource Name (ARN)。

JSON_payload

所呼叫之 Lambda 函數的承載 (JSON 格式)。

注意

Aurora MySQL 第 3 版支援來自 MySQL 8.0 的 JSON 解析函數。不過,Aurora MySQL 第 2 版不包含這些函數。當 Lambda 函數傳回最小單位值時,例如數字或字串,就不需要 JSON 剖析。

lambda_async 函數範例

下列以 lambda_async 為基礎的查詢使用函式 ARN,以非同步叫用 Lambda 函式 BasicTestLambda。函數的承載為 {"operation": "ping"}

SELECT lambda_async( 'arn:aws:lambda:us-east-1:123456789012:function:BasicTestLambda', '{"operation": "ping"}');

叫用觸發條件內的 Lambda 函數

您可以在資料修改陳述式上使用觸發條件來呼叫 Lambda。下列範例會使用 lambda_async 原生函數,並將結果存放在變數中。

mysql>SET @result=0; mysql>DELIMITER // mysql>CREATE TRIGGER myFirstTrigger AFTER INSERT ON Test_trigger FOR EACH ROW BEGIN SELECT lambda_async( 'arn:aws:lambda:us-east-1:123456789012:function:BasicTestLambda', '{"operation": "ping"}') INTO @result; END; // mysql>DELIMITER ;
注意

觸發條件不是針對每一 SQL 陳述式來執行一次,而是每修改一列就執行一次,而且一次只針對一列。觸發程序執行時,處理程序是同步的。只有在觸發程序完成時,才會傳回資料修改陳述式。

從發生高寫入流量的資料表上的觸發程序叫用 AWS Lambda 函數時,請務必小心。 INSERTUPDATE、和DELETE觸發程序會每列啟動。具有INSERTUPDATEDELETE觸發程序的資料表上需要大量寫入的工作負載會導致對函數進行大量呼叫。 AWS Lambda

使用 Aurora MySQL 預存程序叫用 Lambda 函式 (已棄用)

您可以呼叫程mysql.lambda_async序,從 Aurora MySQL 資料庫叢集叫用 AWS Lambda 函數。當您想要將 Aurora MySQL 上執行的資料庫與其他 AWS 服務整合時,此方法非常有用。例如,每當資料庫的特定資料表中插入一列時,您可能想要使用 Amazon Simple Notification Service (Amazon SNS) 傳送通知。

Aurora MySQL 版本考量

從 Aurora MySQL 第 2 版開始,您可以使用原生函數方法,而不是這些預存程序來叫用 Lambda 函數。如需原生函數的詳細資訊,請參閱使用原生函數呼叫 Lambda 函數

Aurora MySQL 第 2 版不再支援預存程序 mysql.lambda_async。強烈建議改用原生 Lambda 函數。

在 Aurora MySQL 第 3 版中,無法使用預存程序。

使用 mysql.lambda_async 程序呼叫 Lambda 函數 (已棄用)

mysql.lambda_async 程序是內建的預存程序,可非同步叫用 Lambda 函式。資料庫使用者必須有 EXECUTE 預存程序的 mysql.lambda_async 權限,才能使用此程序。

語法

mysql.lambda_async 程序的語法如下。

CALL mysql.lambda_async ( lambda_function_ARN, lambda_function_input )

參數

mysql.lambda_async 程序具有下列參數。

lambda_function_ARN

要呼叫之 Lambda 函數的 Amazon Resource Name (ARN)。

lambda_function_input

所呼叫之 Lambda 函數的輸入字串 (JSON 格式)。

範例

在最佳實務上,建議您將 mysql.lambda_async 程序的呼叫包裝在預存程序中,即可供不同來源呼叫,例如觸發條件或用戶端程式碼。此方法有助於避免阻抗不符問題,讓您輕鬆呼叫 Lambda 函數。

注意

從發生高寫入流量的資料表上的觸發程序叫用 AWS Lambda 函數時,請務必小心。 INSERTUPDATE、和DELETE觸發程序會每列啟動。具有 INSERTUPDATEDELETE 觸發條件之資料表上的大量寫入工作負載,會導致對 AWS Lambda 函數的大量呼叫。

雖然呼叫 mysql.lambda_async 程序為非同步執行,但觸發條件是同步執行。導致觸發條件大量引發的陳述式不會等待 AWS Lambda 函數呼叫完成,但會等待觸發條件完成才將控制權交回用戶端。

範例:叫用傳送電子郵件的 AWS Lambda 函數

下列範例建立預存程序,供您在資料庫程式碼中利用 Lambda 函數來呼叫,以傳送電子郵件。

AWS Lambda 函數

import boto3 ses = boto3.client('ses') def SES_send_email(event, context): return ses.send_email( Source=event['email_from'], Destination={ 'ToAddresses': [ event['email_to'], ] }, Message={ 'Subject': { 'Data': event['email_subject'] }, 'Body': { 'Text': { 'Data': event['email_body'] } } } )

預存程序

DROP PROCEDURE IF EXISTS SES_send_email; DELIMITER ;; CREATE PROCEDURE SES_send_email(IN email_from VARCHAR(255), IN email_to VARCHAR(255), IN subject VARCHAR(255), IN body TEXT) LANGUAGE SQL BEGIN CALL mysql.lambda_async( 'arn:aws:lambda:us-west-2:123456789012:function:SES_send_email', CONCAT('{"email_to" : "', email_to, '", "email_from" : "', email_from, '", "email_subject" : "', subject, '", "email_body" : "', body, '"}') ); END ;; DELIMITER ;

叫用預存程序來叫用 AWS Lambda 函式

mysql> call SES_send_email('example_from@amazon.com', 'example_to@amazon.com', 'Email subject', 'Email content');
範例:叫用 AWS Lambda 函數以從觸發器發佈事件

下列範例建立預存程序來使用 Amazon SNS 發佈事件。當資料表中新增一列時,程式碼會從觸發條件呼叫程序。

AWS Lambda 函數

import boto3 sns = boto3.client('sns') def SNS_publish_message(event, context): return sns.publish( TopicArn='arn:aws:sns:us-west-2:123456789012:Sample_Topic', Message=event['message'], Subject=event['subject'], MessageStructure='string' )

預存程序

DROP PROCEDURE IF EXISTS SNS_Publish_Message; DELIMITER ;; CREATE PROCEDURE SNS_Publish_Message (IN subject VARCHAR(255), IN message TEXT) LANGUAGE SQL BEGIN CALL mysql.lambda_async('arn:aws:lambda:us-west-2:123456789012:function:SNS_publish_message', CONCAT('{ "subject" : "', subject, '", "message" : "', message, '" }') ); END ;; DELIMITER ;

資料表

CREATE TABLE 'Customer_Feedback' ( 'id' int(11) NOT NULL AUTO_INCREMENT, 'customer_name' varchar(255) NOT NULL, 'customer_feedback' varchar(1024) NOT NULL, PRIMARY KEY ('id') ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

觸發條件

DELIMITER ;; CREATE TRIGGER TR_Customer_Feedback_AI AFTER INSERT ON Customer_Feedback FOR EACH ROW BEGIN SELECT CONCAT('New customer feedback from ', NEW.customer_name), NEW.customer_feedback INTO @subject, @feedback; CALL SNS_Publish_Message(@subject, @feedback); END ;; DELIMITER ;

在資料表中插入一列以觸發通知

mysql> insert into Customer_Feedback (customer_name, customer_feedback) VALUES ('Sample Customer', 'Good job guys!');