컬럼에 "COLLATE utf8mb4_unicode_ci" 를 삭제하고 싶다면 다음을 진행한다.


1. 테이블 스키마에 COLLATE utf8mb4_unicode_ci 를 먼저 삭제한다.
> ALTER TABLE samuel_test DEFAULT CHARACTER SET utf8mb4;


2. 그다음에 컬럼에 COLLATE utf8mb4_unicode_ci 삭제한다 (먼저 컬럼 속성을 변경하지 않는다)

> ALTER TABLE samuel_test CHANGE `SESSION_ID` `SESSION_ID` char(36) NOT NULL; 




예시는 다음과 같다.  아래와 같은 테이블이 있다.



DROP TABLE samuel_test;


# dummy

CREATE TABLE `samuel_test` (

  `id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,

  `name` bigint(20) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;



# 안바뀐다. 

ALTER TABLE samuel_test CHANGE `id` `id` char(36) NOT NULL;



# 먼저 테이블 스키마에 COLLATE 부분을 먼저 정리

ALTER TABLE samuel_test DEFAULT CHARACTER SET utf8mb4;


# 테이블 스키마에 COLLATE 부분이 정리된 것을 확인할 수 있다.

SHOW CREATE TABLE samuel_test;


ALTER TABLE samuel_test CHANGE `id` `id` char(36) NOT NULL;


SHOW CREATE TABLE samuel_test;



이제 제대로 정리되었음을 알 수 있다.



samuel_test, CREATE TABLE `samuel_test` (

  `id` char(36) NOT NULL,

  `name` bigint(20) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4


Posted by 김용환 '김용환'


Waiting for table metadata lock 재현하기 


이 때 의도적으로 지연해야 하기 sleep 함수를 사용한다.

https://dev.mysql.com/doc/refman/8.0/en/miscellaneous-functions.html#function_sleep


* A session - 일반 계정


start transaction;

select * from target_ids_job_execution where sleep(1000)=0;


* B session - root


MariaDB [test]> ALTER TABLE target_ids_job_execution  add column xxx char(32) default 'xyz';

행(hang)


* C Session - root

show processlist; 



sleep을 포함한 sql 쿼리가 끝나도 여전히 alter table은 hang 걸려 있다. lock에 잡혀 있다. 



따라서 KILL 6을 실행해 metadata lock에 걸려 있는 쿼리를 종료시킨다.


show processlist를 실행하면 다음과 같은 결과가 나타난다.






Posted by 김용환 '김용환'

Warning: Using a password on the command line interface can be insecure 

에러를 해결하려면

 

https://knight76.tistory.com/entry/mariadbmysqldbWarning-Using-a-password-on-the-command-line-interface-can-be-insecure 처럼 진행해야 한다.

 

[mariadb/mysqldb]Warning: Using a password on the command line interface can be insecure

shell 에서 mysql db접속시 패스워드를 입력하면 mysql 5.6 부터는 Warning 문구가 발생한다. $ mysql #{database} -u#{username} -p#{password} Warning: Using a password on the command line interface can be..

knight76.tistory.com

그러나, 테스트 환경 (CI/CD) 구축때는 조금 꼭 이렇게 하는게 부담스러울 수 있는데..-p패스워드 처럼 편한게 어디 있나.. 

 

그래서 에러 출력만 안나오게 하는 방법이 있다. 2> /dev/null를 이용하는 방법이 좋을 수 있다.

 

 

docker-compose exec -T mysql mysql -uroot -p패스워드 -e "set global general_log=on" 2> /dev/null

 

그러나 확인할 때는 > /dev/null 2>1 를 사용할 수 도 있다. 

 

 is_success=$(docker-compose exec -T mysql mysql -uroot -p패스워드 -e "show databases" > /dev/null 2>1 && echo "true")

 

Posted by 김용환 '김용환'



mysql에서 timestamp 컬럼을 추가할 때 주의할 점이 있다. 


timestamp 컬럼 그 자체로 타입을 정의하면, 밀리초(millisecond)는 나타나지 않는다.


timestamp(1)은  소수점 첫번째자리,

timestamp(2)는 소수점 두번째 자리를 표현한다.


그래서 최대 6자리 까지 정확도를 높일 수 있다.







https://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html




MySQL 5.6.4 and up expands fractional seconds support for TIMEDATETIME, and TIMESTAMP values, with up to microseconds (6 digits) precision:

  • To define a column that includes a fractional seconds part, use the syntax type_name(fsp), where type_name is TIMEDATETIME, or TIMESTAMP, and fsp is the fractional seconds precision. For example:

    CREATE TABLE t1 (t TIME(3), dt DATETIME(6));

    The fsp value, if given, must be in the range 0 to 6. A value of 0 signifies that there is no fractional part. If omitted, the default precision is 0. (This differs from the standard SQL default of 6, for compatibility with previous MySQL versions.)

  • Inserting a TIMEDATE, or TIMESTAMP value with a fractional seconds part into a column of the same type but having fewer fractional digits results in rounding. Consider a table created and populated as follows:

    CREATE TABLE fractest( c1 TIME(2), c2 DATETIME(2), c3 TIMESTAMP(2) );
    INSERT INTO fractest VALUES
    ('17:51:04.777', '2018-09-08 17:51:04.777', '2018-09-08 17:51:04.777');

    The temporal values are inserted into the table with rounding:

    mysql> SELECT * FROM fractest;
    +-------------+------------------------+------------------------+
    | c1          | c2                     | c3                     |
    +-------------+------------------------+------------------------+
    | 17:51:04.78 | 2018-09-08 17:51:04.78 | 2018-09-08 17:51:04.78 |
    +-------------+------------------------+------------------------+


Posted by 김용환 '김용환'



특정 장비에서 mysql DB로 


telnet은 접속이 안되었지만, 아래와 같은 mysql client 에러가 발생해 mysql에서 따로 deny하고 있는 줄 알았는데..



ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 104



알고보니 방화벽 ACL이었다..


Posted by 김용환 '김용환'





sql console로는 update_date 컬럼에 between..and 를 검색했더니 잘 동작했다.


select hostname, domain from server where update_date BETWEEN '2018-11-28' AND '2018-11-28 23:59:59'



코드에 반영했지만 아래와 같은 에러가 발생했다.


ORA-01843: not a valid month


아래 쿼리로 확인해도 정상적으로 AMERICAN으로 잘 나왔다.



select * from nls_session_parameters where parameter = NLS_DATE_LANGUAGE;





원인은 컬럼에 timestamp 타입인지 명시하지 않아서 발생한 것이다. 


따라서 아래와 같이 TO_TIMESTAMP를 사용하는 방식을 사용하면 정상적으로 작동한다.



select hostname, domain from server where update_date BETWEEN  TO_TIMESTAMP('2018-11-28 00:00:00', 'YYYY-MM-DD HH24:MI:SS') AND TO_TIMESTAMP('2018-11-28 23:59:59', 'YYYY-MM-DD HH24:MI:SS')



Posted by 김용환 '김용환'



ORA-00933: SQL 명령어가 올바르게 종료되지 않았습니다



보통 이 에러가 발생하면 SQL 문법 에러이다. SQL 툴에서 잘 동작하는지 확인하고.


아니면, 세미콜론(;)이 뒤에 붙어 있는지 확인하면 좋다.

Posted by 김용환 '김용환'


회사에서 발생했던 mysql driver 의 크리티컬 이슈 


5.1.45 이상 버전으로 업그레이드가 피요하다.


https://bugs.mysql.com/bug.php?id=88242




Added the following entry to the Connector/J 5.1.45 changelog: "Normally, when the socketTimeout option has been set and a socket timeout occurs on the client side, the server may continue working and returning query results. At the next query executed after the timeout, Connector/J first clears the socket input stream and then sends a ping request to the server. However, an error occurred if the autoReconnect option was set to true and, after reconnection, a new query was executed by Connector/J, and the results from the previous queries arrived before Connector/J sent its ping request to the server, in which case the old packages might be mistaken as results for the new query. This fix corrects the issue by forcibly closing the network resources after a communication or IO exception. The next statement execution recreates the IO stream if autoReconnect=true; otherwise, the connection stays closed."


Posted by 김용환 '김용환'

mysql 완전 삭제

DB 2017.09.27 15:29



mysql 서버를 설치하고 삭제후 재설치할 때,

기존 정보가 섞여서 지저분할 때가 있다. 꼭 다음 스크립트를 돌리는 게.. 정신적으로 편하다.




출처 : stackoverflow(기억이 안남..)


sudo -i

service mysql stop

killall -KILL mysql mysqld_safe mysqld

apt-get --yes purge mysql-server mysql-client

apt-get --yes autoremove --purge

apt-get autoclean

deluser --remove-home mysql

delgroup mysql

rm -rf /etc/apparmor.d/abstractions/mysql /etc/apparmor.d/cache/usr.sbin.mysqld /etc/mysql /var/lib/mysql /var/log/mysql* /var/log/upstart/mysql.log* /var/run/mysqld

updatedb



Posted by 김용환 '김용환'





이제는 5.7부터는 secure-auth 옵션을 mysql에 사용할 수 없다.


mysql에서는 4.1이전의 암호화 방법이 있었다. 대부분 이 방식을 많은 mysql 언어별 라이브러리에서 사용하고 있었다. mysql을 사용하는 애플리케이션의 구버전을 migration할 때 이 부분을 주의할 필요가 있다.


mysql 5.7을 설치하고 python 구(old) sqlalchemy에서 mysql에 접근하면 아래와 같은 에러가 발생한다. 


InternalError: (InternalError) (1251, u'Client does not support authentication protocol requested by server; consider upgrading MySQL client') None None




--skip-secure-auth, --secure-auth=0을 사용하면 secure-auth를 0으로 설정하지 못한다는 에러가 발생하고 mysqld이 실행되지 않는다. 


https://dev.mysql.com/doc/refman/5.7/en/mysql-command-options.html#option_mysql_secure-auth


--secure-auth


Do not send passwords to the server in old (pre-4.1) format. This prevents connections except for servers that use the newer password format.


As of MySQL 5.7.5, this option is deprecated and will be removed in a future MySQL release. It is always enabled and attempting to disable it (--skip-secure-auth, --secure-auth=0) produces an error. Before MySQL 5.7.5, this option is enabled by default but can be disabled.







Posted by 김용환 '김용환'