# CentOS 6 이하 버전
shell > service mysql start
shell > service mysql stop
# CentOS 7 이상버전
shell > systemctl start mariadb
shell > systemctl stop mariadb
shell > sh ${MariaDB설치위치}/support-files/mysql.server start
shell > sh ${MariaDB설치위치}/support-files/mysql.server stop
# 또는
shell > ${MariaDB설치위치}/bin/mysqld_safe --defaults-file=/etc/my.cnf &
shell > mysaladmin -u root -p shutdown
shell > mysaladmin -h 192.168.0.1 -P 3307 -u root -p shutdown
# 로컬 로그인
[root@localhost mysql]# mysql -u root -p
# 원격지 로그인 시
[root@localhost mysql]# mysql -h 127.0.0.1 -P 3306 -u root -p
# 연결 정보 조회
MariaDB [(none)]> \s
--------------
mysql Ver 15.1 Distrib 10.1.22-MariaDB, for Linux (x86_64) using readline 5.1
Connection id: 3
Current database:
Current user: root@localhost
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server: MariaDB
Server version: 10.1.22-MariaDB MariaDB Server
Protocol version: 10
Connection: 127.0.0.1 via TCP/IP
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
TCP port: 3306
Uptime: 3 min 39 sec
Threads: 1 Questions: 6 Slow queries: 0 Opens: 17 Flush tables: 1 Open tables: 11 Queries per second avg: 0.027
--------------
# 안전모드로 mysql 클라이언트 실행
[root@localhost mysql]# mysql -u root -p --safe-updates;
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 5
Server version: 10.1.22-MariaDB MariaDB Server
Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> use test;
Database changed
MariaDB [test]> create table test_table(uid int); <---- 가능
Query OK, 0 rows affected (0.01 sec)
MariaDB [test]> insert into test_table values (1); <---- 가능
Query OK, 1 row affected (0.01 sec)
MariaDB [test]> select * from test_table; <---- 가능
+------+
| uid |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
MariaDB [test]> delete from test_table; <--- 불가능
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
MariaDB [test]> update test_table set uid = 2; <---- 불가능
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
# 쿼리문 실행 시 --execute 옵션 사용
[root@localhost mysql]# mysql -u root -p -D test --execute="select * from test_table"
Enter password:
+------+
| uid |
+------+
| 1 |
+------+
예:
권한범위 | 권한 | 설명 |
---|---|---|
전역 | CREATE USER | 사용자 생성 |
전역 | FILE | LOAD DATA INFILE 같은 디스크의 파일 접근 시 필요한 권한 |
전역 | PROCESS | MariaDB내의 프로세스 조회 권한 |
전역 | RELOAD | FLUSH를 실행할 수 있는 권한 |
전역 | SHUTDOWN | 서버를 종료할 수 있는 권한 |
전역 | SUPER | 특정한 상황에서 제한을 넘어서 뭔가를 할 수 있는 권한 예) read_only 설정 시 데이터 변경 가능 |
데이터베이스 레벨 | CREATE | 새로운 데이터 베이스 생성 |
데이터베이스 레벨 | DROP | 데이터베이스 삭제 |
데이터베이스 레벨 | GRANT OPTION | 데이터베이스의 권한을 다른 사용자에게 부여할 수 있는 권한 |
데이터베이스 레벨 | EVENT | 이벤트 생성 및 삭제 |
데이터베이스 레벨 | LOCK TABLE | 명시적으로 테이블을 잠그는 권한 |
테이블 레벨 | ALTER | 테이블 구조 변경 |
테이블 레벨 | CREATE | 테이블 생성 |
테이블 레벨 | DELETE | 레코드 삭제 |
테이블 레벨 | DROP | 테이블 삭제 |
테이블 레벨 | GRANT OPTION | 테이블에 대한 권한을 다른 사용자에게 부여할 수 있는 권한 |
테이블 레벨 | INSERT | 레코드 입력 |
테이블 레벨 | SELECT | 레코드 조회 |
테이블 레벨 | UPDATE | 레코드 수정 |
STORED PROGRAM | ALTER ROUTIN | 프로시저/함수 등 변경 |
STORED PROGRAM | EXECUTE | 프로시저/함수 등 실행 |
STORED PROGRAM | GRANT OPTION | 프로시저/함수 등의 권한을 다른 사용자에게 부여할 수 있는 권한 |
# 권한만 부여
MariaDB [(none)]> grant 권한목록 on db.table to 'user'@'host';
# 계정을 생성하고 권한까지 부여
MariaDB [(none)]> grant 권한목록 on db.table to 'user'@'host' identified by 'password' with grant option;
# 글로벌 권한 부여
MariaDB [(none)]> grant super on *.* to 'jigi'@'%';
# 데이터베이스 권한 부여
MariaDB [(none)]> grant event on *.* to 'jigi'@'%';
MariaDB [(none)]> grant event on test.* to 'jigi'@'%';
# 테이블 권한 부여
MariaDB [(none)]> grant select,insert,update,delete on *.* to 'jigi'@'%';
MariaDB [(none)]> grant select,insert,update,delete on test.* to 'jigi'@'%';
MariaDB [(none)]> grant select,insert,update,delete on test.test_table to 'jigi'@'%';
MariaDB [(none)]> grant select,insert,update(uid) on test.test_table to 'jigi'@'%'; <-- update는 uid 컬럼만 가능하다.
# 권한 그룹(role)생성
MariaDB [(none)]> create role dba; <-- 해당 롤을 만든 사용자만 롤 권한 부여가능
MariaDB [(none)]> create role developer with admin jigi; <-- 해당 롤을 만든 사용자와 jigi 계정만 롤 권한 부여가능
MariaDB [(none)]> grant all privileges on *.* to dba; <-- 모든 권한을 dba 롤에 부여
MariaDB [(none)]> grant select,insert,update,delete on test.* to developer; <-- test 데이터베이스의 select, DML 권한만 developer 롤에 부여
# 롤 부여 및 제거
MariaDB [(none)]> set role dba; <-- 롤 부여
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> select current_role;
+--------------+
| current_role |
+--------------+
| dba |
+--------------+
1 row in set (0.00 sec)
MariaDB [(none)]> set role developer;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> select current_role; <--- 롤은 한 계정에 한 개만 적용된다. (2개 이상 불가능)
+--------------+
| current_role |
+--------------+
| developer |
+--------------+
1 row in set (0.00 sec)
ariaDB [(none)]> set role none;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> select current_role; <--- 롤 제거
+--------------+
| current_role |
+--------------+
| NULL |
+--------------+
1 row in set (0.00 sec)
MariaDB [mysql]> select user, host from user;
+-----------+-----------------------+
| user | host |
+-----------+-----------------------+
| dba | |
| developer | |
| jigi | % |
| root | 127.0.0.1 |
| root | ::1 |
| root | localhost |
| root | localhost.localdomain |
+-----------+-----------------------+
7 rows in set (0.00 sec)
MariaDB [mysql]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema | <-- 메타 데이터가 저장되는 데이터베이스
| mysql | <-- 사용자 인증정보, stored program, 이벤트 정보 등이 저장되는 기본 데이터베이스
| performance_schema | <-- 각종 이벤트, 잠금, 잠금 대기 등의 정보를 기록하는 테이블 구조 저장, 매 기동될때 마다 초기화되며, 데이터는 메모리에 저장
| test | <-- 테스트용 데이터베이스(삭제하는 것이 보안상 좋음)
+--------------------+
4 rows in set (0.00 sec)
MariaDB [mysql]> create database firstdb;
MariaDB [mysql]> create database firstdb default character set utf8mb4;
MariaDB [mysql]> drop database firstdb;
MariaDB [mysql]> grant show database on *.* to 'abc'@'%' identified by 'test_password';
MariaDB [mysql]> grant select, insert, update, delete on firstdb.* to 'abc'@'%';
MariaDB [mysql]> flush privileges;
* 참고사항 : 사용자 계정과 데이터베이스는 전혀 무관하게 이원화되어 관리되므로, 데이터 베이스는 따로 만들어야 된다.
# root 계정은 너무 많이 알려졌으므로, 로컬만 접속가능한 별도의 관리자계정을 만드는 것을 추천한다.
MariaDB [mysql]> grant all on *.* to 'superman'@'localhost' identified by 'adminpass' with grant option;
MariaDB [mysql]> grant all on *.* to 'superman'@'127.0.0.1' identified by 'adminpass' with grant option;
MariaDB [mysql]> flush privileges;
MariaDB [test]> create table if not exists abc (col1 int, col2 varchar(100)) engine=innodb;
MariaDB [test]> show create table abc;
+-------+-------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------------------------------------------------+
| abc | CREATE TABLE `abc` (
`col1` int(11) DEFAULT NULL,
`col2` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+-------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
MariaDB [test]> desc abc;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| col1 | int(11) | YES | | NULL | |
| col2 | varchar(100) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
MariaDB [test]> create table t1(fd1 int, fd2 enum('red', 'gree'));
Query OK, 0 rows affected (0.03 sec)
MariaDB [test]> alter online table t1 modify fd2 enum('red','green','blue');
ERROR 1846 (0A000): LOCK=NONE is not supported. Reason: Cannot change column type INPLACE. Try LOCK=SHARED.
MariaDB [test]> alter online table t1 modify fd2 enum('red','gree','blue');
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [test]> alter online table t1 add fd3 int;
Query OK, 0 rows affected (0.07 sec)
Records: 0 Duplicates: 0 Warnings: 0
# LOCK = {DEFAULT | NONE | SHARED | EXCLUSIVE }
* NONE : 온라인 DDL이 실행되는 동안 테이블에 읽기/쓰기가 가능
* SHARED : 읽기만 가능
* DEFAULT : LOCK를 명시하지 않은 것과 같음
# ALGORITHM = { DEFAULT | INPLACE | COPY }
* COPY : MySQL 5.5이하 버전에서 사용되던 방법으로 데이터를 임시 테이블로 모두 복사후, rename하는 방식
* INPLACE : MySQL 5.6이상 버전에서 지원되는 방법으로, 데이터를 바로 변경하되, 변경 작업시 일어나는 DML작업들은 별도의 로그로 보관했다가 데이터 변경 마지막에 일괄 적용하는 방법
* DEFAULT : ALGORITHM를 명시하지 않은 것과 같음
# inplace 방식은 온라인 변경 로그의 공간을 충분히 할당해야 메모리 공간 부족으로 작업이 실패하지 않는다.
MariaDB [test]> alter table t1 add fd4 varchar(20), lock=none, algorithm=inplace;
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
# auto-increment 컬럼은 LOCK=SHARED 모드로 지정해야 된다.
MariaDB [test]> alter table t1 add fd5 int auto_increment primary key, lock=none, algorithm=inplace;
ERROR 1846 (0A000): LOCK=NONE is not supported. Reason: Adding an auto-increment column requires a lock. Try LOCK=SHARED.
온라인 스키마 변경 작업이 실패할 수 있는 경우
수행과정 |
---|
1. 기존 테이블에 insert/delete/update AFTER 트리거를 생성하여, 데이터 변경 시 새로운 테이블로 전달 할 수 있도록 한다. 2. 모든 레코드를 복사하고 나면, RENAME 명령어를 통해 기존 테이블과 새 테이블의 이름을 변경한다. 3. RENAME 명령어는 한 트랜잭션 내에서 처리할 수 있기 때문에, RENAME 수행도중 다른 트랜젝션 쿼리는 실패하지 않는다. 4. 주의사항 : 기존 테이블에 이미 AFTER 트리거가 있는 경우 사용할 수 없고, PK와 유니크 인덱스가 있는 경우 데드락 상태가 빈번하게 발생할 수 있다. |
MariaDB [test]> drop table t1;
MariaDB [test]> drop table if exists t1;
* 주의사항 : ext3 파일 시스템에서 실제 물리적인 데이터 파일삭제 시 많은 시간을 소모하므로, 테이블 크기가 큰 경우 새벽시간에 작업하는 것이 좋다.
# 사용할 데이터베이스 변경
MariaDB [test]> use mysql;
MariaDB [mysql]>
# 테이블 생성
MariaDB [test]> create table tab_test(fd1 int, fd2 varchar(50), primary key(fd1)) engine = innodb;
MariaDB [test]> insert into tab_test values (1, 'matt');
MariaDB [test]> insert into tab_test values (2, 'toto');
# 데이터 입력 및 조회
MariaDB [test]> insert into tab_test values (3, 'Lee') on duplicate key update fd2='Lee';
MariaDB [test]> select * from tab_test;
+-----+------+
| fd1 | fd2 |
+-----+------+
| 1 | matt |
| 2 | toto |
| 3 | Lee |
+-----+------+
3 rows in set (0.00 sec)
# 동일 데이터가 이미 있을 경우 fd2를 Seonguck으로 업데이트 한다.
MariaDB [test]> insert into tab_test values (3, 'Seonguck') on duplicate key update fd2='Seonguck';
Query OK, 2 rows affected (0.00 sec)
MariaDB [test]> select * from tab_test;
+-----+----------+
| fd1 | fd2 |
+-----+----------+
| 1 | matt |
| 2 | toto |
| 3 | Seonguck |
+-----+----------+
3 rows in set (0.00 sec)
MariaDB [test]> select * from tab_test;
+-----+----------+
| fd1 | fd2 |
+-----+----------+
| 1 | matt |
| 2 | toto |
| 3 | Seonguck |
+-----+----------+
3 rows in set (0.00 sec)
# 세로 형태로 보여준다.
MariaDB [test]> select * from tab_test\G
*************************** 1. row ***************************
fd1: 1
fd2: matt
*************************** 2. row ***************************
fd1: 2
fd2: toto
*************************** 3. row ***************************
fd1: 3
fd2: Seonguck
3 rows in set (0.00 sec)
MariaDB [test]> update tab_test set fd2='123' where fd1 = 3;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [test]> select * from tab_test;
+-----+------+
| fd1 | fd2 |
+-----+------+
| 1 | matt |
| 2 | toto |
| 3 | 123 |
+-----+------+
3 rows in set (0.00 sec)
MariaDB [test]> replace tab_test set fd1=1, fd2='aaa';
Query OK, 2 rows affected (0.00 sec)
MariaDB [test]> select * from tab_test;
+-----+------+
| fd1 | fd2 |
+-----+------+
| 1 | aaa |
| 2 | toto |
| 3 | 123 |
+-----+------+
3 rows in set (0.00 sec)
MariaDB [test]> replace tab_test set fd1=4, fd2='bbbb';
Query OK, 1 row affected (0.01 sec)
MariaDB [test]> select * from tab_test;
+-----+------+
| fd1 | fd2 |
+-----+------+
| 1 | aaa |
| 2 | toto |
| 3 | 123 |
| 4 | bbbb |
+-----+------+
4 rows in set (0.00 sec)
# replace절에서는 where절은 사용하지 못한다.
MariaDB [test]> replace tab_test set fd1=4, fd2='bbbb' where fd1=4;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'where fd1=4' at line 1
MariaDB [test]> delete from tab_test where fd1=1;
Query OK, 1 row affected (0.00 sec)
MariaDB [test]> select * from tab_test;
+-----+------+
| fd1 | fd2 |
+-----+------+
| 2 | toto |
| 3 | 123 |
| 4 | bbbb |
+-----+------+
3 rows in set (0.00 sec)