- with(nolock) 은...
set transaction isolation level read uncommitted;
로 해결.


- TOP은 LIMIT로 변경.
ex.
SELECT TOP 10 * FROM books
-->
SELECT * FROM books LIMIT 10;


- IF는 ENDIF와 pair여야한다.
ex.
IF (condition) THEN
do sth;
END IF;


- Auto increment
ex.
SET @id = @@IDENTITY
SET @id = IDENTITY_CURRENT()
-->
SET @id = LAST_INSERT_ID();

- Stored Procedure
delimiter를 이용해 ;를 변경하고 다시 원상복귀
ex.
delimiter //
CREATE PROCEDURE xProc
do sth;
END;
//
delimeter ;


- Data type 비교

수치 자료형


MySQL
Size
SQL
Server 2000

TINYINT
1 Byte
TINYINT
SMALLINT 2 Bytes SMALLINT
MEDIUMINT 3 Bytes
INT 4 Bytes INT
INTEGER 4 Bytes INT
BIGINT 8 Bytes BIGINT
FLOAT(X<=24) 4 Bytes FLOAT(0)
FLOAT(25<=X<=53)
8 Bytes FLOAT(25)
DOUBLE 8 Bytes FLOAT(25)
DOUBLE PRECISION 8 Bytes FLOAT(53)
REAL 8 Bytes REAL
DECIMAL M Bytes(D+2, if M<D)
DECIMAL
NUMERIC M Bytes(D+2, if M<D) NUMERIC

날짜 시간 자료형



MySQL Size SQL er 2000
DATE
3 Bytes SMALLDATETIME
DATETIME 8 Bytes DATETIME
TIMESTAMP 4 BytesTIMESTAMP
TIME 3 Bytes SMALLDATETIME
YEAR 1 Byte
SMALLDATETIME

 
문자열형


MySQL
Size SQL Server 2000
CHAR(m) M Bytes, 1<=M<=255 CHAR
VARCHAR(m) L+1
Bytes where L<=M and 1<=M<=255
VARCHAR

TINYBLOB
L + 1 Bytes where L<2^8 BINARY
BLOB L + 2 Bytes where L<2^16
VARBINARY
TEXT L + 2 Bytes where L<2^16 TEXT
MEDIUMBLOB L + 3 Bytes where L<2^24 IMAGE
MEDIUMTEXT L + 3 Bytes where L<2^24 TEXT
LONGBLOB L + 4 Bytes where L<2^32 IMAGE
LONGTEXT L + 4 Bytes where L<2^32 TEXT
ENUM
(VALUE1, VALUE2, …)
데이터형이 1또는 2바이트를차지하는지는 그값의 수치로판단된다. 매칭되는 자료형이 없으나 CHECK 제약을
이용해 구현 가능하다.
SET
(VALUE1, VALUE2, …)
1, 2, 3, 4 또는 8 바이트

Set 멤버들의 최대값에 의존적인 값이다.




AND

MySQL 한글 설정

개발/mysql 2008. 2. 18. 16:01
아놔, 한글 설정 너무 어렵다...
이럴때는 한글 쓰는게 정말 서럽다.
자나깨나 한글설정 조심. --+

MySQL 5.0 한글 설정(utf8, euckr)
http://maxnim.tistory.com/1166706275

MySQL 5.0 설치팁
http://www.javamaster.org/lecture/mysql/mysql_install.html

mysql-데이터베이스 설치(utf-8 설정)
http://ikinox.tistory.com/entry/mysql-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%84%A4%EC%B9%98utf-8-%EC%84%A4%EC%A0%95

ex.
euc-kr인 경우에는 다음과 같이 설정한다.
(난, utf8이 조은데... )

my.cnf를 다음과 같이 고친다.
(utf8인 경우는 euckr만 utf8로 수정)

[mysql]
default-character-set = euckr

[mysqld]
character-set-client-handshake=FALSE
init_connect="SET collation_connection = euckr_korean_ci"
init_connect="SET NAMES euckr"
default-character-set = euckr
character-set-server = euckr

collation-server = euckr_korean_ci

[client]
default-character-set = euckr

[mysqldump]
default-character-set = euckr

결과 확인은 mysql 내에서,
status; 나
show variables; 로 확인 가능하다.

AND

개인적으로 삽질했던 문제해결 리스트(Troubleshooting List)  2탄

Slave 재부팅시에 Slave가 동작하지 않는 경우가 발생한다면?

master.info와 relay-log.info를 확인하여,
설정이 유효한지 확인한다.

그런데도, syslog에 아래와 같은 문제가 발생한다면?

[Warning] Neither --relay-log nor --relay-log-index were used; so replication may break when this MySQL server acts as a slave and has his hostname changed!! Please use '--relay-log=/var/run/mysqld/mysqld-relay-bin' to avoid this problem.

my.cnf에 relay-log 설정을 추가한다.

그럼에도 불구하고 다음과 같이 에러가 계속 된다면?

[ERROR] Failed to open the relay log '/var/run/mysqld/mysqld-relay-bin.000045'

원하는 relay-log를 찾지 못하는 현상이 일어나므로,
relay-log의 위치를 변경한다.

일반적으로 /var/run에는 재부팅 전까지만 유효한 내용들을 넣어두므로,
다른 안전한 곳으로 옮기는 것도 괜찮다.

옮기는 김에, relay-log.info, master.info의 위치도 변경해 보자.
여기서는 좀 부잡스럽지만 일단 /var/log/mysql 아래에 다 넣는다.

relay-log = /var/log/mysql/mysqld-relay-bin
master-info-file = /var/log/mysql/master.info
relay-log-info-file = /var/log/mysql/relay-log.info


AND

pymssql을 MySQLdb로 이전할 때,
인터페이스 상으로는 DB API 2.0을 둘다 지원하니 크게 바꿀 부분이 없을 것 같네요.

connect 함수의 입력인자 password, database 가 passwd, db 로만 바꿔주면 될 듯...

ex.
conn = MySQLdb.connect(
   host = '아무데나',
   user = '아무나',
   passwd = '****',
   db = 'dbname'
)
cs = conn.cursor()
cs.execute(sql)
res = cs.fetchall()
...

그 외에 문제가 넘처 흐르겠지만,
추후에 정리할 날이 온다면 정리할랍니다 :)
AND

초간단 Replication overview

Replication은 master의 내용을 여러 slave들에게 복사본을 유지시키는 것을 의미한다.
즉, 아래 그림의 경우와 같이 write는 비교적 적게 일어나고,
read가 자주 일어나는 웹사이트들의 경우에 load balancing을 위해 사용할 수 있을 것이다.


그림 출처: http://dev.mysql.com/doc/refman/5.0/en/replication-solutions-scaleout.html

Replication 관련 주의해야할 사항 및 troubleshooting 관련글들은 아래 mysql 사이트를 참조하도록 한다.
http://dev.mysql.com/doc/refman/5.0/en/replication-features.html



개인적으로 삽질했던 문제해결 리스트(Troubleshooting List) ...

1. replication 후 slave에서 master에 연결이 안될 때.

slave로 master의 db를 dump를 하게 되면,
user 정보들도 모두 dump하게 된다.

즉, 다음에 slave를 리부팅했을 경우 오류가 날 수 있다.
일례로 /etc/mysql/debian.cnf 안에 보면,
password가 master의 것으로 바뀌게 되므로 slave의 세팅을
master의 세팅과 동일하게 맞춰주어야 될 지도 모른다.


2. slave 혹은 master의 문제로 인해 다시 동기화를 해야할 경우.

dump한 후 다시 stop, start slave를 시킨다.
혹시 relay-log를 못 따라가며 안되면,... 무식하게,
mysql> RESET SLAVE;
를 한 후, 다시 설정/시작 시킨다..

3. Slave가 꺼져있는 동안 Master에서 update가 일어나는 경우.

Slave에서 동기화 에러가 날 수 있다.
다시 동기화할때 Slave단에서 duplication 등의 에러가 날 수 있는데,
(무시해 줘도 되는 경우...)
그리 치명적인 에러가 아니면 my.cnf 내에서 slave-skip-errors 옵션을
이용해서 무시해주면 된다.
slave-skip-errors = 1061, 1062
모든 에러를 다 건너뛰려면, slave-skip-errors = all 로 세팅하면 된다.


4. 에러가 난 경우, 해당 쿼리를 확인/건너뛰는 방법.

우선 Slave에서 Exec_Master_Log_Pos 위치 확인.
mysql> SHOW SLAVE STATUS\G

Master에서 근처에 어떤 쿼리가 있는지 확인.
mysql> SHOW BINLOG EVENTS IN 'mysql-bin.000032' FROM 13633 LIMIT 3 \G

문제가 없다면 다음 위치로 이동.
mysql> SLAVE STOP;
mysql> CHANGE MASTER TO
MASTER_LOG_FILE='mysql-bin.000032',
MASTER_LOG_POS=13770;
mysql> SLAVE START;
mysql> SHOW SLAVE STATUS \G

혹은 확인 결과 현재 에러가 skip해도 된다면,
mysql> SLAVE STOP;
mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
mysql> SLAVE START;

AND

Mysql Master-Master Replication 설정하기
(Dual-Master replication)
: Master-Slave의 설정을 역으로 동일하게 한다고 생각하면 된다.

0. Master-Slave Replication이 설정되어 있다고 가정한다.
  설정이 끝날때 까지 기존 Master, Slave 명칭을 유지한다. 
 
1. Slave에 Master로의 replication을 위한 'repl' 계정을 만들고 권한을 준다.

mysql> GRANT REPLICATION SLAVE ON . TO 'repl'@'%.dsphome.net' IDENTIFIED BY '****';

2. Master에서 Slave를 master로 여기도록 설정한다.

mysql> CHANGE MASTER TO
-> MASTER_HOST='slave hostname/ip',
-> MASTER_USER='repl',
-> MASTER_PASSWORD='****',
-> MASTER_LOG_FILE='mysql-bin.000027',
-> MASTER_LOG_POS=9080;
 
물론 이 설정을 위해서는 Slave의 master_log 정보를 적어놔야한다.
( 기본 replication 설정 참고 )

3. master의 slave를 재시작시킨다.

mysql> START SLAVE;

4. 양쪽 모두 작동하는지 확인.

mysql> SHOW SLAVE STATUS\G


AND

0. START/STOP : 말그대로 start, stop 시킨다.

mysql> START SLAVE;
mysql> STOP SLAVE;

1. RESET Syntax : binary log를 리셋시킨다.

mysql> RESET MASTER;
mysql> RESET SLAVE;

2. SHOW Syntax : 여러가지 상태들을 보여준다.

mysql> SHOW MASTER STATUS;
mysql> SHOW SLAVE STATUS;

mysql> SHOW PROCESSLIST\G

*************************** 1. row ***************************
    Id: 35
  User: root
  Host: localhost
    db: NULL
Command: Query
  Time: 0
  State: NULL
  Info: show processlist
*************************** 2. row ***************************
    Id: 37
  User: repl
  Host: blog2.local:55297
    db: NULL
Command: Binlog Dump
  Time: 306
  State: Has sent all binlog to slave; waiting for binlog to be updated
  Info: NULL
2 rows in set (0.00 sec)


cf. \G는 vertical로 결과를 표시해준다.
AND


기본적인 방법은 "Mysql Replication 설정하기"와 동일하며,
해당글의 '6번 Slave'를 시작하기 전에 다음의 작업을 추가로 하면 된다.

1. Master에서 모든 테이블을 flush.

mysql> FLUSH TABLES WITH READ LOCK;

2. mysqldump를 이용해서 Master의 내용을 dump.

shell> mysqldump --all-databases --lock-all-tables >dbdump.db

권한이 모자라면 -u root -p 등의 옵션을 추가로 주면 된다.

3. Slave를 잠시 멈춘다.

기존에 돌아가던 slave가 있는 경우에만 해당된다.

mysql> STOP SLAVE;

4. Master로부터 dump한 dbdump.db 파일을 rsync등으로 가져와서, Import 시킨다.
   
shell> mysql < dbdump.db

이번에도 역시 권한이 모자라면 -u root -p 등의 옵션을 추가로 주면 된다.

5. Slave를 재시작.

mysql> START SLAVE;

Slave의 db를 select해보면 정상적으로 동기화 된 것을 확인할 수 있을 것이다.

AND

Replication 설정

0) Slave, Master 서버 설정 변경
Master의 /etc/mysql/my.cnf에서
아래와 같이 binary logging과 server-id를 체크한다.

[mysql]
log-bin=mysql-bin
server-id=1

Slave의 /etc/mysql/my.cnf에서
아래와 같이server-id가 겹치지 않도록 수정한다.

[mysql]
server-id=2

1) master와 slave에 동일한 버전의 mysql 설치( 본인의 경우에는 5.0 설치 )

2) replication용 user 추가( 여기서는 repl로 설정 )

mysql> CREATE USER userid IDENTIFIED BY 'password';

3) replication slave용 user를 master에서 권한 설정.

mysql> grant replication slave on *.* to 'repl'@'%.dsphome.net' identified by '****';

4) Slave의 설정을 위해서 Master의 binary log 정보를 보자.

mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000027 |     9080 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

mysql> UNLOCK TABLES;

5) Slave에서 Master 세팅 설정.
/etc/mysql/my.cnf를 수정해도 되며, 아래와 같이 명령을 날려도 된다.
아래 각 항목의 값들 중, log_file과 log_pos는 위의 master status의 값을 적는다.

mysql> CHANGE MASTER TO
   -> MASTER_HOST='hostname/ip',
   -> MASTER_USER='repl',
   -> MASTER_PASSWORD='****',
   -> MASTER_LOG_FILE='mysql-bin.000027',
   -> MASTER_LOG_POS=9080;

6) Slave 시작.

mysql> START SLAVE;

7) Slave 상태 확인.

mysql> show slave status \G;
*************************** 1. row ***************************
            Slave_IO_State: Waiting for master to send event
               Master_Host: blog1.naver.com (예입니다)
               Master_User: repl
               Master_Port: 3306
             Connect_Retry: 60
           Master_Log_File: mysql-bin.000027
       Read_Master_Log_Pos: 9080
            Relay_Log_File: mysqld-relay-bin.000022
             Relay_Log_Pos: 235
     Relay_Master_Log_File: mysql-bin.000027
          Slave_IO_Running: Yes
         Slave_SQL_Running: Yes
           Replicate_Do_DB:
       Replicate_Ignore_DB:
        Replicate_Do_Table:
    Replicate_Ignore_Table:
   Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
                Last_Errno: 0
                Last_Error:
              Skip_Counter: 0
       Exec_Master_Log_Pos: 169
           Relay_Log_Space: 235
           Until_Condition: None
            Until_Log_File:
             Until_Log_Pos: 0
        Master_SSL_Allowed: No
        Master_SSL_CA_File:
        Master_SSL_CA_Path:
           Master_SSL_Cert:
         Master_SSL_Cipher:
            Master_SSL_Key:
     Seconds_Behind_Master: 0
1 row in set (0.00 sec)

Slave_IO_State가 위와 같이 나오지 않고,
'Connecting to master' 등 다른 상태이면 network상태를 의심해봐야 한다.
ping으로 network 연결 상태를 보고,

이도 정상적인 경우에는 skip-networking 옵션이 켜 있는 경우일 것이다.

# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address       = 127.0.0.1

이 부분의 주소를 수정하고 재시작하도록 한다.

MySQL 재 시작
$ sudo /etc/init.d/mysql restart


이제 master의 변화가 slave에 반영되는 것을 확인할 수 있다.
AND

기본적인 mysql의 명령어들 정리.

1. 사용자 추가하기
1) root로 접속.
mysql> mysql -u root -p
Enter Password : ****

2) 사용자 추가.
mysql> USE mysql;
mysql> INSERT INTO user (host,user,password) VALUES('localhost','username',password('****'));

3) sudo /etc/init.d/mysql restart 혹은
mysql> FLUSH PRIVILEGES;

4) 사용자 삭제.
mysql>DELETE FROM user WHERE user='username';

2. DB 추가하기
1) root로 접속.
mysql> mysql -u root -p
Enter Password : ****

2) database 추가
mysql> CREATE DATABASE dbname;
mysql> GRANT ALL PRIVILEGES ON dbname.* TO username@localhost IDENTIFIED BY '****';


물론 mysql-query-browser를 설치했다면 gui상에서 해도 크게 무방함.
AND