Loading...
MySQL 9.5 Reference Manual 9.5의 27.3.5 JavaScript Stored Programs—Session Information and Options의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
MySQL에서 저장 루틴에 대한 일반적인 정보는
Section 27.2, “Using Stored Routines”를 참조하십시오.
MLE 컴포넌트는 MLE 사용자 세션을 다루기 위한 여러 로더블 함수(loadable function)를 제공합니다. 이 함수들은 다음과 같이 나열되고 설명됩니다:
이 함수를 인자를 주지 않고 호출하면 현재 MLE 세션 상태를 정리하여,
mle_session_state()에 의해 관찰 가능한 출력(output)을 제거합니다. 또한 세션 타임 존을 재설정하여, 이후 JavaScript 저장 루틴 호출 시 세션에서 가장 최근에 설정된 타임 존이 사용되게 합니다.
이 함수는 선택적인 문자열 인자를 하나 받습니다. 가능한 값과 그 효과는 다음과 같습니다:
"stdout": stdout을 지웁니다.
"stderr": stderr를 지웁니다.
"output": stdout과 stderr 둘 다를 지웁니다.
이 함수를 인자 없이 호출하는 것은 이전 MySQL 버전에서와 같이 계속 동작하며, stderr와 stdout 둘 다를 지우고, 스택 트레이스를 지우며 세션 타임 존을 재설정합니다.
이 로더블 함수를 사용하여, 가장 최근에 실행된 MLE 저장 프로그램에 대한 세션 정보를 얻을 수 있습니다.
mle_session_state()는 하나의 인자를 받는데, 세션 상태 키(문자열)이며, 이에 대응하는 세션 상태 값을 보여 줍니다. 세션 상태 값은 최대 크기 64K(16000개의 4바이트 문자에 해당)로 제한됩니다. 이는 순환(cyclic) 버퍼이며, 사용 가능한 공간이 소진되면 새로운 엔트리가 가장 오래된 엔트리를 덮어씁니다. 가능한 세션 상태 키들은 그 설명과 함께 다음과 같습니다:
is_active: 현재 MySQL 사용자 세션이 MLE 세션이면 1을, 그렇지 않으면 0을 반환합니다.
stdout: 저장 프로그램이 console.log()를 사용하여 기록한 모든 내용을 출력합니다.
stderr: 저장 프로그램이 console.error()를 사용하여 기록한 모든 내용을 출력합니다.
stack_trace: MLE 저장 프로그램의 실행이 실패한 경우, 오류의 원인을 찾는 데 도움이 될 수 있는 스택 트레이스를 포함합니다.
실패한 CREATE FUNCTION 또는
CREATE PROCEDURE 구문 및 유사한 오류는 여기에 기록되지 않고, 저장 함수 또는 저장 프로시저의 실행 도중 발생한 런타임 오류만 기록됩니다.
stored_functions: 현재 세션에서 캐시된 저장 함수의 개수를 반환합니다.
stored_procedures: 현재 세션에서 캐시된 저장 프로시저의 개수를 반환합니다.
stored_programs: 현재 세션에서 캐시된 저장 프로그램(저장 함수와 저장 프로시저)의 개수를 반환합니다.
세션 상태 키는 리터럴 문자열 값이며 반드시 따옴표로 감싸야 합니다.
어떤 MLE 저장 프로그램도 호출되기 전에, 이 세 가지 세션 상태 값은 모두 비어 있습니다. 클라이언트를 종료하고 세션을 다시 시작하면 이 값들은 모두 지워집니다.
다음 두 예제는 세션 상태 값들을 조회하는 방법을 보여 줍니다. 먼저, 모든 세션 상태 값을 표시하는 저장 프로시저 mle_states()를 다음과 같이 생성합니다:
1mysql> delimiter // 2mysql> CREATE PROCEDURE mle_states() 3 -> BEGIN 4 -> SELECT 5 -> mle_session_state("is_active") AS '-ACTIVE-', 6 -> mle_session_state("stdout") AS '-STDOUT-', 7 -> mle_session_state("stderr") AS '-STDERR-', 8 -> mle_session_state("stack_trace") AS '-STACK-', 9 -> mle_session_state("stored_functions") AS '-FUNCS-', 10 -> mle_session_state("stored_procedures") AS '-PROCS-', 11 -> mle_session_state("stored_programs") AS '-PROGS-'; 12 -> END// 13Query OK, 0 rows affected (0.02 sec) 14 15mysql> delimiter ;
어떤 MLE 저장 프로그램도 실행하기 전에는,
mle_states()의 출력에 있는 값들은 모두 0이거나 비어 있으며, 다음과 같습니다:
1mysql> CALL mle_states(); 2+----------+----------+----------+---------+---------+---------+---------+ 3| -ACTIVE- | -STDOUT- | -STDERR- | -STACK- | -FUNCS- | -PROCS- | -PROGS- | 4+----------+----------+----------+---------+---------+---------+---------+ 5| 0 | | | | 0 | 0 | 0 | 6+----------+----------+----------+---------+---------+---------+---------+ 71 row in set (0.00 sec) 8 9Query OK, 0 rows affected (0.00 sec)
이제 JavaScript 저장 프로시저 pc1()을 생성하는데,
이 프로시저는 짧은 루프 내에서 console.log()와 console.error()를 사용하여 여러 번 stdout과 stderr에 기록합니다:
1mysql> CREATE PROCEDURE pc1() 2 -> LANGUAGE JAVASCRIPT AS 3 -> $$ 4 $> let x = 0 5 $> 6 $> do { 7 $> console.log(`This is message #${++x} to stdout.`) 8 $> console.error(`This is message #${x} to stderr.`) 9 $> } 10 $> while(x < 3) 11 $> $$ 12 -> ; 13Query OK, 0 rows affected (0.02 sec)
방금 보인 CREATE PROCEDURE 구문이 실행된 후,
mle_states()는 활성 MLE 세션을 보여 줍니다.
아직 어떤 저장 프로그램도 실행되지 않았으므로 어떤 것도 캐시되지 않았습니다. 따라서 JavaScript 저장 함수, 프로시저 및 프로그램을 반영하는 컬럼들은 모두 0을 보여 줍니다. 출력은 다음과 같습니다:
1mysql> CALL mle_states; 2+----------+----------+----------+---------+---------+---------+---------+ 3| -ACTIVE- | -STDOUT- | -STDERR- | -STACK- | -FUNCS- | -PROCS- | -PROGS- | 4+----------+----------+----------+---------+---------+---------+---------+ 5| 1 | | | | 0 | 0 | 0 | 6+----------+----------+----------+---------+---------+---------+---------+ 71 row in set (0.00 sec) 8 9Query OK, 0 rows affected (0.00 sec)
Note
backtick (`````) 문자로 문자열을 감싸면 출력에서 변수 보간(variable interpolation)을 사용할 수 있습니다. 이 quoting 메커니즘에 익숙하지 않은 경우, Mozilla Developer의 Template Literals를 참조하십시오.
pc1()을 호출한 다음
mle_states()를 호출하면 다음과 같은 결과가 생성됩니다:
1mysql> CALL pc1(); 2Query OK, 0 rows affected (0.00 sec) 3 4mysql> CALL mle_states()\G 5*************************** 1. row *************************** 6-ACTIVE-: 1 7-STDOUT-: This is message #1 to stdout. 8This is message #2 to stdout. 9This is message #3 to stdout. 10 11-STDERR-: This is message #1 to stderr. 12This is message #2 to stderr. 13This is message #3 to stderr. 14 15 -STACK-: 16 -FUNCS-: 0 17 -PROCS-: 1 18 -PROGS-: 1 191 row in set (0.00 sec) 20 21Query OK, 0 rows affected (0.00 sec)
저장 프로시저를 실행하면 MLE 세션이 시작되므로
is_active (-ACTIVE-)는 이제 1입니다.
같은 세션 내에서 stdout 또는
stderr에 연속으로 쓰면 기존 콘텐츠에 추가(append)됩니다. 이를 보기 위해
pc1()을 다시 호출한 후
mle_states()의 출력을 확인하면 다음과 같습니다:
1mysql> CALL pc1(); 2Query OK, 0 rows affected (0.00 sec) 3 4mysql> CALL mle_states()\G 5*************************** 1. row *************************** 6-ACTIVE-: 1 7-STDOUT-: This is message #1 to stdout. 8This is message #2 to stdout. 9This is message #3 to stdout. 10This is message #1 to stdout. 11This is message #2 to stdout. 12This is message #3 to stdout. 13 14-STDERR-: This is message #1 to stderr. 15This is message #2 to stderr. 16This is message #3 to stderr. 17This is message #1 to stderr. 18This is message #2 to stderr. 19This is message #3 to stderr. 20 21 -STACK-: 22 -FUNCS-: 0 23 -PROCS-: 1 24 -PROGS-: 1 251 row in set (0.00 sec) 26 27Query OK, 0 rows affected (0.00 sec)
pc1()에 의해 오류가 발생하지 않았으므로 스택 트레이스는 비어 있습니다. 스택 트레이스를 테스트하기 위해, pc1()의 수정된 복사본을 생성하여 console.log() 참조를 정의되지 않은 함수인 console.lob()으로 변경할 수 있습니다:
1mysql> CREATE PROCEDURE pc2() 2 -> LANGUAGE JAVASCRIPT AS 3 -> $$ 4 $> let x = 0 5 $> do { 6 $> console.lob(`This is message #${++x} to stdout.`) 7 $> console.error(`This is message #${x} to stderr.`) 8 $> } 9 $> while(x < 3) 10 $> $$ 11 -> ; 12Query OK, 0 rows affected (0.02 sec)
1CREATE PROCEDURE pc2() 2LANGUAGE JAVASCRIPT AS 3 $$ 4 let x = 0 5 do { 6 console.lob(`This is message #${++x} to stdout.`) 7 console.error(`This is message #${x} to stderr.`) 8 } 9 while(x < 3) 10 $$ 11;
1mysql> CREATE PROCEDURE pc2() 2 -> LANGUAGE JAVASCRIPT AS 3 -> $$ 4 $> let x = 0 5 $> do { 6 $> console.lob(`This is message #${++x} to stdout.`) 7 $> console.error(`This is message #${x} to stderr.`) 8 $> } 9 $> while(x < 3) 10 $> $$ 11 -> ; 12Query OK, 0 rows affected (0.02 sec)
CREATE PROCEDURE 구문은 성공적으로 실행되지만,
pc2()를 호출하려 하면 다음과 같이 오류가 발생합니다:
1mysql> CALL pc2(); 2ERROR 6113 (HY000): JavaScript> TypeError: (intermediate value).lob is not a function
그 후 다시 mle_states()를 호출하면, 같은 세션 내에 있으므로
stdout 및 stderr 필드는 여전히 이전에 기록된 콘텐츠를 포함하고 있음을 볼 수 있습니다. 방금 보인 오류의 스택 트레이스는 출력의 마지막 컬럼에 표시됩니다:
1mysql> CALL mle_states()\G 2*************************** 1. row *************************** 3-ACTIVE-: 1 4-STDOUT-: This is message #1 to stdout. 5This is message #2 to stdout. 6This is message #3 to stdout. 7This is message #1 to stdout. 8This is message #2 to stdout. 9This is message #3 to stdout. 10 11-STDERR-: This is message #1 to stderr. 12This is message #2 to stderr. 13This is message #3 to stderr. 14This is message #1 to stderr. 15This is message #2 to stderr. 16This is message #3 to stderr. 17 18-STACK-: <js> pc2:3:6-54 19 20-FUNCS-: 0 21-PROCS-: 2 22-PROGS-: 2 231 row in set (0.00 sec) 24 25Query OK, 0 rows affected (0.00 sec)
또한 mle_session_state()의
stored_functions,
stored_procedures,
stored_programs 키 값은 각각 0, 2, 2입니다. JavaScript 저장 프로시저를 2개 생성했으며 JavaScript 저장 함수는 없으므로, JavaScript 저장 프로그램은 총 2개입니다.
스택 트레이스는 JavaScript 저장 프로그램 호출 간에 유지되지 않습니다.
mle_states()의 출력에 있는 모든 필드의 정보를 지우려면, 다음과 같이 mle_session_reset()을 호출합니다:
1mysql> SELECT mle_session_reset(); 2mysql> SELECT mle_session_reset(); 3+------------------------------------------+ 4| mle_session_reset() | 5+------------------------------------------+ 6| The session state is successfully reset. | 7+------------------------------------------+ 81 row in set (0.00 sec)
다시 mle_states()를 호출하면, 어떤 저장 JavaScript 저장 프로그램도 사용되기 전의 초기 결과와 동일한 결과가 생성됩니다.
1mysql> CALL mle_states; 2+----------+----------+----------+---------+---------+---------+---------+ 3| -ACTIVE- | -STDOUT- | -STDERR- | -STACK- | -FUNCS- | -PROCS- | -PROGS- | 4+----------+----------+----------+---------+---------+---------+---------+ 5| 0 | | | | 0 | 0 | 0 | 6+----------+----------+----------+---------+---------+---------+---------+ 71 row in set (0.00 sec) 8 9Query OK, 0 rows affected (0.00 sec)
또는, JavaScript 루틴 내부에서 console.clear()를 사용하여
stdout 및 stderr를 지울 수 있습니다.
MLE 컴포넌트는 현재 세션 동안 MySQL 정수 타입(TINYINT,
SMALLINT, MEDIUMINT,
INT, BIGINT)
과 MySQL 고정소수점 타입
(DECIMAL,
NUMERIC)을 JavaScript 값으로 변환할 때 적용되는 규칙을 결정하기 위한 수단으로 이 함수를 제공합니다.
이 규칙은 JavaScript 프로그램의 입력 인자뿐만 아니라 결과 집합의 값에도 적용됩니다.
정수 타입(키: integer_type)에 대한 가능한 변환 규칙은 다음과 같으며, 이름별로 나열됩니다:
BIGINT: 항상 JavaScript BigInt로 변환합니다.
STRING: 항상 JavaScript String으로 변환합니다.
UNSAFE_BIGINT: 값이 안전한 경우 JavaScript Number로 변환하고, 그렇지 않으면 JavaScript BigInt로 변환합니다.
UNSAFE_STRING: 값이 안전한 경우 JavaScript Number로 변환하고, 그렇지 않으면 JavaScript String으로 변환합니다. 규칙이 지정되지 않은 경우 기본 동작입니다.
이러한 변환 규칙의 문맥에서 “안전한(safe)”이란, 변환될 값이
-(253-1)
(-9007199254740991)에서
(253-1)
(9007199254740991) 사이(포함)에 있는 것을 의미합니다.
MySQL 고정소수점 타입은 JavaScript Number 또는 String 값으로 변환될 수 있으며,
어느 타입이 사용되는지 결정하기 위해, 키
decimal_type으로 mle_set_session_state()를 호출할 수 있습니다. 이 키는 다음 두 값 중 하나를 가질 수 있습니다:
STRING: MySQL
DECIMAL 또는 NUMERIC 값은 JavaScript String으로 변환됩니다.
NUMBER: MySQL
DECIMAL 또는 NUMERIC 값은 JavaScript Number로 변환됩니다.
mle_set_session_state() 또는 JavaScript 저장 루틴 내부의
Session.setOptions()에 의해 재정의되지 않는 한,
기본값은 MySQL 고정소수점 타입을 JavaScript String으로 변환하는 것입니다.
이 함수는 현재 사용자 세션에 캐시된 저장 프로그램이 없을 때만 호출할 수 있습니다. 성공하면 함수는 1을 반환합니다. 그렇지 않고 호출을 시도하면 다음과 같이 오류가 발생합니다:
1mysql> SELECT gcd(536, 1676); // Call JS stored function 2+----------------+ 3| gcd(536, 1676) | 4+----------------+ 5| 4 | 6+----------------+ 71 row in set (0.00 sec) 8 9mysql> SELECT mle_set_session_state('{"integer_type":"BIGINT"}'); 10ERROR 1123 (HY000): Can't initialize function 'mle_set_session_state'; Cannot 11set options of an active session. Please reset the session first.
오류 메시지에서 알 수 있듯이, 활성 세션을 지우려면 세션을 재설정해야 합니다. 이를 위해 다음과 같이
mle_session_reset()을 사용하십시오:
1mysql> SELECT mle_session_reset(); 2+------------------------------------------+ 3| mle_session_reset() | 4+------------------------------------------+ 5| The session state is successfully reset. | 6+------------------------------------------+ 71 row in set (0.00 sec)
이제 다음과 같이 mle_set_session_state()를 호출할 수 있습니다:
1mysql> SELECT mle_set_session_state('{"integer_type":"BIGINT"}'); 2+----------------------------------------------------+ 3| mle_set_session_state('{"integer_type":"BIGINT"}') | 4+----------------------------------------------------+ 5| 1 | 6+----------------------------------------------------+ 71 row in set (0.00 sec) 8 9mysql> SELECT mle_set_session_state('{"decimal_type":"Number"}'); 10+----------------------------------------------------+ 11| mle_set_session_state('{"decimal_type":"Number"}') | 12+----------------------------------------------------+ 13| 1 | 14+----------------------------------------------------+ 151 row in set (0.00 sec)
특정 쿼리를 실행하기 전에 JavaScript API
Session의 sql(), runSql(), prepare()와 같은 메서드를 사용하여 변환 타입을 설정할 수 있습니다.
자세한 내용과 예제는
Session.sql()의 설명을 참조하십시오.
MLE 컴포넌트의 리소스 사용량 정보는 Performance Schema의
memory_summary_by_thread_by_event_name
및
memory_summary_global_by_event_name
테이블을, 각 MLE 사용자 세션의 메모리 사용량을 추적하는 키
memory/language_component/session으로 조회하여 얻을 수 있습니다. 이 키는 MLE 컴포넌트에서 제공하며,
MLE 컴포넌트가 설치되면
setup_instruments 테이블에 다음과 같이 포함됩니다:
1mysql> SELECT * FROM performance_schema.setup_instruments 2 > WHERE NAME LIKE '%language_component%'\G 3*************************** 1. row *************************** 4 NAME: memory/language_component/session 5 ENABLED: YES 6 TIMED: NULL 7 PROPERTIES: controlled_by_default 8 FLAGS: controlled 9 VOLATILITY: 0 10DOCUMENTATION: Session-specific allocations for the Language component 111 row in set (0.00 sec)
어떤 JavaScript 저장 프로그램, 쿼리, MLE를 생성하거나 실행하기 전에 MLE는 비활성 상태로 유지되므로, 이 키를 사용하면 다음과 같이 비어 있거나 대부분이 0으로 이루어진 결과가 반환됩니다:
1mysql> SELECT * FROM performance_schema.memory_summary_by_thread_by_event_name 2 -> WHERE 3 -> EVENT_NAME = 'memory/language_component/session' 4 -> AND 5 -> COUNT_ALLOC < 0\G 6Empty set (0.02 sec) 7 8mysql> SELECT * FROM performance_schema.memory_summary_global_by_event_name 9 -> WHERE EVENT_NAME LIKE 'memory/language_component/%'\G 10*************************** 1. row *************************** 11 EVENT_NAME: memory/language_component/session 12 COUNT_ALLOC: 0 13 COUNT_FREE: 0 14 SUM_NUMBER_OF_BYTES_ALLOC: 0 15 SUM_NUMBER_OF_BYTES_FREE: 0 16 LOW_COUNT_USED: 0 17 CURRENT_COUNT_USED: 0 18 HIGH_COUNT_USED: 0 19 LOW_NUMBER_OF_BYTES_USED: 0 20CURRENT_NUMBER_OF_BYTES_USED: 0 21 HIGH_NUMBER_OF_BYTES_USED: 0 221 row in set (0.01 sec)
JavaScript 저장 함수를 호출한 후에는, 같은 쿼리들이 이제 다음과 같이 MLE가 사용한 메모리를 반영합니다:
1mysql> SELECT * FROM performance_schema.memory_summary_by_thread_by_event_name 2 -> WHERE 3 -> EVENT_NAME = 'memory/language_component/session' 4 -> AND 5 -> COUNT_ALLOC < 0\G 6*************************** 1. row *************************** 7 THREAD_ID: 46 8 EVENT_NAME: memory/language_component/session 9 COUNT_ALLOC: 25 10 COUNT_FREE: 20 11 SUM_NUMBER_OF_BYTES_ALLOC: 4445 12 SUM_NUMBER_OF_BYTES_FREE: 2989 13 LOW_COUNT_USED: 0 14 CURRENT_COUNT_USED: 5 15 HIGH_COUNT_USED: 14 16 LOW_NUMBER_OF_BYTES_USED: 0 17CURRENT_NUMBER_OF_BYTES_USED: 1456 18 HIGH_NUMBER_OF_BYTES_USED: 3239 191 row in set (0.00 sec) 20 21mysql> SELECT * FROM performance_schema.memory_summary_global_by_event_name 22 -> WHERE EVENT_NAME LIKE 'memory/language_component/%'\G 23*************************** 1. row *************************** 24 EVENT_NAME: memory/language_component/session 25 COUNT_ALLOC: 25 26 COUNT_FREE: 20 27 SUM_NUMBER_OF_BYTES_ALLOC: 4445 28 SUM_NUMBER_OF_BYTES_FREE: 2989 29 LOW_COUNT_USED: 0 30 CURRENT_COUNT_USED: 5 31 HIGH_COUNT_USED: 14 32 LOW_NUMBER_OF_BYTES_USED: 0 33CURRENT_NUMBER_OF_BYTES_USED: 1456 34 HIGH_NUMBER_OF_BYTES_USED: 3239 351 row in set (0.00 sec)
이들 및 관련 Performance Schema 테이블에 대한 자세한 내용은
Section 29.12.20.10, “Memory Summary Tables”를 참조하십시오.
특정 사용자 세션에서 MLE 컴포넌트의 메모리 사용량은
connection_memory_limit 서버 시스템 변수에 의해 부과되는 제한을 받습니다. 자세한 내용은 이 변수의 설명을 참조하십시오.
27.3.4 JavaScript Stored Program Data Types and Argument Handling
27.3.6 JavaScript SQL API