사용자 도구

사이트 도구


database:mysql:jdbc

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
database:mysql:jdbc [2020/03/05 10:48]
kwon37xi
database:mysql:jdbc [2024/01/16 09:53] (현재)
kwon37xi [sessionVariables]
줄 16: 줄 16:
     * MySQL 5.0 이하에서는 PreparedStatement 사용으로 인한 이점이 거의 없어서 ClientPreparedStatement로 사용해도 무관하다.     * MySQL 5.0 이하에서는 PreparedStatement 사용으로 인한 이점이 거의 없어서 ClientPreparedStatement로 사용해도 무관하다.
     * MySQL 5.1 이상에서는 제대로 PreparedStatement가 서버사이드에서 구현되었고 PrepraedStatement에도 쿼리 캐시가 적용되었다. - 근데 테스트해보니 안빠르고 오히려 더 느린데?? 테스트 철저히 하고 사용여부 결정할 것.     * MySQL 5.1 이상에서는 제대로 PreparedStatement가 서버사이드에서 구현되었고 PrepraedStatement에도 쿼리 캐시가 적용되었다. - 근데 테스트해보니 안빠르고 오히려 더 느린데?? 테스트 철저히 하고 사용여부 결정할 것.
-  * PreparedStatemtn 사용 분석<code sql>+  * ''PreparedStatement'' 사용 분석<code sql>
 SELECT * FROM information_schema.global_status SELECT * FROM information_schema.global_status
 WHERE variable_name IN ('Com_stmt_prepare', 'Com_stmt_execute', 'Prepared_stmt_count'); WHERE variable_name IN ('Com_stmt_prepare', 'Com_stmt_execute', 'Prepared_stmt_count');
줄 41: 줄 41:
   * 8.0 드라이버 부터는 ''sslMode''프라퍼티로 변경된다.   * 8.0 드라이버 부터는 ''sslMode''프라퍼티로 변경된다.
   * ''useSSL=false|false'', ''sslMode=DISABLED'' 로 항상 원하는 상태를 명시할것.   * ''useSSL=false|false'', ''sslMode=DISABLED'' 로 항상 원하는 상태를 명시할것.
- 
  
 ==== Datetime 0 ==== ==== Datetime 0 ====
줄 55: 줄 54:
  
 ===== Replication JDBC Driver ===== ===== Replication JDBC Driver =====
-  * 계속 사용해본 결과 **Replication Driver는 사용하지 않는 것이 좋겠다**.+  * 계속 사용해본 결과 **Replication Driver는 사용하지 않는 것이 좋겠다 -> 2023년 현재 최신 드라이버는 괜찮을 수 있음.**.
     * Java 사용시에는 [[java:jdbc:replication|Java JDBC Replication Connection Pool(DataSource)]] 을 참조한다.     * Java 사용시에는 [[java:jdbc:replication|Java JDBC Replication Connection Pool(DataSource)]] 을 참조한다.
-    * read/write 중 한쪽작업으로 몰릴 경우 Connection Pool입장에서는 어쨌든 사용중인 커넥션이므로 ping 쿼리가 다른쪽으로는 날라가지 않아서 간헐적으로 사용되는 커넥션이 끊기는 일이 발생한다. +    * read/write 중 한쪽작업으로 몰릴 경우 Connection Pool입장에서는 어쨌든 사용중인 커넥션이므로 ping 쿼리가 다른쪽으로는 날라가지 않아서 간헐적으로 사용되는 커넥션이 끊기는 일이 발생한다. (**근본적으로 ping 없이 connection 유지 시간을 끊기는 시간보다 작게 잡는게 더 좋을것 같긴 하다**) 
-    * ping이 안날라가서 끊기는 문제는 Proxy나 MySQL서버의 접속 끊는 시간 이전에 커넥션 풀에서 커넥션을 무조건 끊고 다시 맺는 옵션을 주면 해결된다.(BoneCP, DBCP2 등은 이런 옵션을 제공한다)+    * ping이 안날라가서 끊기는 문제는 Proxy나 MySQL서버의 접속 끊는 시간 이전에 커넥션 풀에서 커넥션을 무조건 끊고 다시 맺는 옵션을 주면 해결된다.(''maxLifeTime'')
     * 일반적으로 Master보다는 Slave에 커넥션이 많이 필요한데 이 드라이버를 사용하면 항상 동수의 커넥션을 맺는다. 따라서 Master에 불필요한 커넥션 수 증가가 발생한다.     * 일반적으로 Master보다는 Slave에 커넥션이 많이 필요한데 이 드라이버를 사용하면 항상 동수의 커넥션을 맺는다. 따라서 Master에 불필요한 커넥션 수 증가가 발생한다.
     * JVM의 메모리 점유율이 높아지는 것 같다. ReplicationDriver를 사용하면 Full GC 빈도가 더 높아지는 현상이 발견되었다.     * JVM의 메모리 점유율이 높아지는 것 같다. ReplicationDriver를 사용하면 Full GC 빈도가 더 높아지는 현상이 발견되었다.
-    * ping 문제만 해결하면 사용 자체에 큰 문제는 없다.+    * ping 문제만 해결하면 사용 자체에 큰 문제는 없다. -> 해결됨.
  
-  * [[http://dev.mysql.com/doc/connector-j/en/connector-j-master-slave-replication-connection.html|MySQL :: MySQL Connector/J Developer Guide :: 8.3 Master/Slave Replication with ReplicationConnection]]+  * [[https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-source-replica-replication-connection.html|MySQL :: MySQL Connector/8.0 Developer Guide :: 9.4 Configuring Source/Replica Replication with Connector/J]]
   * Connection.setReadOnly()에 지정된 값에 따라 쓰기일 때는 마스터, 그 외에는 슬레이브로 보내는 처리를 해준다. Spring @Transactional(readOnly="true|false")   * Connection.setReadOnly()에 지정된 값에 따라 쓰기일 때는 마스터, 그 외에는 슬레이브로 보내는 처리를 해준다. Spring @Transactional(readOnly="true|false")
     * [[http://www.dragishak.com/?p=307|MySQL Master/Slave Load Balancing with JPA and Spring]] 단순히 @Transactional만으로는 Master/Slave를 제대로 찾지 못한다는 글. -> Spring 4.1 미만에서는 JPA의 @Transactional이 ''connection.setReadOnly()''를 호출하지 않음. 호출하게 강제로 해주던가 4.1 이상을 사용하던가..     * [[http://www.dragishak.com/?p=307|MySQL Master/Slave Load Balancing with JPA and Spring]] 단순히 @Transactional만으로는 Master/Slave를 제대로 찾지 못한다는 글. -> Spring 4.1 미만에서는 JPA의 @Transactional이 ''connection.setReadOnly()''를 호출하지 않음. 호출하게 강제로 해주던가 4.1 이상을 사용하던가..
줄 74: 줄 73:
     * ''failOverReadOnly=true''     * ''failOverReadOnly=true''
   * To enable this functionality, use the com.mysql.jdbc.ReplicationDriver class when configuring your application server's connection pool or when creating an instance of a JDBC driver for your standalone application. Because it accepts the same URL format as the standard MySQL JDBC driver, ReplicationDriver does not currently work with java.sql.DriverManager-based connection creation unless it is the only MySQL JDBC driver registered with the DriverManager.   * To enable this functionality, use the com.mysql.jdbc.ReplicationDriver class when configuring your application server's connection pool or when creating an instance of a JDBC driver for your standalone application. Because it accepts the same URL format as the standard MySQL JDBC driver, ReplicationDriver does not currently work with java.sql.DriverManager-based connection creation unless it is the only MySQL JDBC driver registered with the DriverManager.
-  * Ping용 쿼리를 주로 ''SELECT 1''을 사용하는데 ReplicationDriver 사용시에는 문제가 된다. 항상 Master/Slave 두개의 커넥션을 유지하는데 이 경우에는 한쪽으로만 쿼리가 실행되기 때문에다. **''/* ping */ SELECT 1''** 이라고 해야 JDBC의 ''ping()'' 함수를 모든 커넥션에 실행한다.[[http://bugs.mysql.com/bug.php?id=22643|MySQL Bug #22643]]+  * Ping용 쿼리를 주로 ''SELECT 1''을 사용하는데 ReplicationDriver 사용시에는 문제가 된다. 항상 Master/Slave 두개의 커넥션을 유지하는데 이 경우에는 한쪽으로만 쿼리가 실행되기 때문에다. **''/* ping */ SELECT 1''** 이라고 해야 JDBC의 ''ping()'' 함수를 모든 커넥션에 실행한다.[[http://bugs.mysql.com/bug.php?id=22643|MySQL Bug #22643]] fixed!
   * ''java.sql.SQLException: No database selected'' 에러가 발생한다면, JDBC URL에 database를 지정하지 않았기 때문이다. MySQL 기본 드라이버는 DB를 지정하지 않고 쿼리에서 DB명을 명시해도 괜찮지만 replication 드라이버는 이 경우 오류를 냄.   * ''java.sql.SQLException: No database selected'' 에러가 발생한다면, JDBC URL에 database를 지정하지 않았기 때문이다. MySQL 기본 드라이버는 DB를 지정하지 않고 쿼리에서 DB명을 명시해도 괜찮지만 replication 드라이버는 이 경우 오류를 냄.
-  * [[http://gywn.net/2012/07/mysql-replication-driver-error-report/|MySQL replication driver 사용시 문제될 수 있는 요소]] -> slave 다운시에는 괜찮으나, master 다운시에는 재접속을 하지 못한다. master가 재시작이 되어도 slave에 대한 속이 복구가 안된다.+  * [[http://gywn.net/2012/07/mysql-replication-driver-error-report/|MySQL replication driver 사용시 문제될 수 있는 요소]] -> slave 다운시에는 괜찮으나, master 다운시에는 재접속을 하지 못한다. master가 재시작이 되어도 slave에 대한 속이 복구가 안된다.
     * 관련 해결책이 5.1.27 에 나온듯.     * 관련 해결책이 5.1.27 에 나온듯.
     * ''allowMasterDownConnections=true''     * ''allowMasterDownConnections=true''
줄 97: 줄 96:
   * MySQL이 생성하는 모든 쿼리의 로그를 남길 수 있다.   * MySQL이 생성하는 모든 쿼리의 로그를 남길 수 있다.
   * ''logger=com.mysql.jdbc.log.Slf4JLogger'' : 로거 지정   * ''logger=com.mysql.jdbc.log.Slf4JLogger'' : 로거 지정
-  * ''profileSQL=true''이면 로그로 모든 쿼리를 남기고 성능 지표도 함께 표시한다.+  * ''profileSQL=true''이면 로그로 모든 쿼리를 남기고 성능 지표도 함께 표시한다. 정확히는 프로파일링 하라라는 뜻이고, ''profilerEventHandler''가 그걸 로그로 남기는 역할을 하는 듯 보임. 
 +  * [[https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-connp-props-debugging-profiling.html|MySQL :: MySQL Connector/J 8.0 Developer Guide :: 6.3.14 Debugging/Profiling]] 
 +  * ''logSlowQueries=true'' 및 하위 설정으로 slow query 자동 설정가능 
 +    * ''slowQueryThresholdMillis'' 
 +    * ''explainSlowQueries=true''
  
 +==== sessionVariables ====
 +  * [[https://dev.mysql.com/doc/connector-j/en/connector-j-connp-props-session.html#cj-conn-prop_sessionVariables|MySQL :: MySQL Connector/J Developer Guide :: 6.3.3 Session]]
 +  * connection 을 맺을 때마다 세션에 대해 ''SET [SESSION] xxx=yyy'' 형태로 설정하는 값들을 JDBC URL에 지정 가능하다.
 +  * https://stackoverflow.com/a/62582767
 +=== 8.x ===
 +<code>
 +jdbc:mysql://[host:port]/[database]/?sessionVariables=&&key1=value1,key2=value2
 +</code>
 +
 +=== 7.x 이전 ===
 +<code>
 +jdbc:mysql://[host:port]/[database]/?sessionVariables=key1=value1,key2=value2
 +</code>
 ===== allowMultiQueries ===== ===== allowMultiQueries =====
   * MySQL JDBC는 기본적으로 하나의 SQL 실행 요청에 여러 SQL을 실행하는 것을 금지하고 있다.(세미콜론(;)으로 여러 SQL 전송 불가)   * MySQL JDBC는 기본적으로 하나의 SQL 실행 요청에 여러 SQL을 실행하는 것을 금지하고 있다.(세미콜론(;)으로 여러 SQL 전송 불가)
database/mysql/jdbc.1583372887.txt.gz · 마지막으로 수정됨: 2020/03/05 10:48 저자 kwon37xi