생계/Oracle2025. 2. 28. 13:57

AWS 환경에서 S3 통한 덤프파일 전달 받아 데이터펌프 사용하기 

# 외부 Oracle 환경에서 expdp 로 덤프 파일 생성

expdp username/password@database_link \
DIRECTORY=data_pump_dir \
DUMPFILE=export_dump.dmp \
SCHEMAS=schema_name \
LOGFILE=export_dump.log

case 1. ec2 oracle  환경에서 impdp 

1) 생성된 덤프 파일 S3 버킷에 업로드

 - AWS CLI를 사용하여 덤프 파일을 S3 버킷에 업로드합니다:

aws s3 cp export_dump.dmp s3://your-bucket-name/export_dump.dmp

2) EC2 인스턴스 접속,  S3 버킷으로부터 덤프 파일 다운로드

 - EC2 인스턴스에 접속합니다:

ssh -i "your-key.pem" ec2-user@your-ec2-instance-public-dns

 - S3 버킷에서 덤프 파일 다운로드

aws s3 cp s3://your-bucket-name/export_dump.dmp /tmp/export_dump.dmp

3) ec2 Oracle 에 impdp 로 데이터 로드

impdp username/password@database \
DIRECTORY=data_pump_dir \
DUMPFILE=export_dump.dmp \
SCHEMAS=schema_name \
LOGFILE=import_dump.log \
TABLE_EXISTS_ACTION=REPLACE

- 작업 후 파일 삭제

aws s3 rm s3://your-bucket-name/export_dump.dmp

case 2. rds oracle  환경에서 impdp 

1) 생성된 덤프 파일 S3 버킷에 업로드

aws s3 cp export_dump.dmp s3://your-bucket-name/export_dump.dmp

2) S3에서 덤프 파일을 다운로드

BEGIN
  rdsadmin.rdsadmin_s3_tasks.download_from_s3(
    p_bucket_name    => 'your-bucket-name',
    p_s3_prefix      => 'export_dump.dmp',
    p_directory_name => 'DATA_PUMP_DIR'
  );
END;
/

3) rds Oracle 에 impdp 로 데이터 로드

DECLARE
  v_hdnl NUMBER;
BEGIN
  v_hdnl := DBMS_DATAPUMP.OPEN(
    operation => 'IMPORT',
    job_mode  => 'SCHEMA',
    job_name  => 'IMPORT_JOB'
  );
  
  DBMS_DATAPUMP.ADD_FILE(
    handle    => v_hdnl,
    filename  => 'export_dump.dmp',
    directory => 'DATA_PUMP_DIR'
  );
  
  DBMS_DATAPUMP.METADATA_FILTER(
    handle => v_hdnl,
    name   => 'SCHEMA_EXPR',
    value  => 'IN (''schema_name'')'
  );
  
  DBMS_DATAPUMP.START_JOB(v_hdnl);
END;
/

# impdp 작업 모니터링

SELECT *
  FROM DBA_DATAPUMP_JOBS 
 WHERE JOB_NAME = 'IMPORT_JOB';
  

반응형
Posted by 돌고래트레이너
생계/DA2025. 1. 10. 00:27

데이터베이스 모델링에서 관계는 결국 컬럼으로 표현이 되는데 이 컬럼이 참조하는 테이블이 자기자신일 때가 있다. 

이를 자기 참조 모델 또는 순환 관계 모델이라고도 부르는데, 어떻게 사용하는지 알아보자.

-- 테이블 생성
CREATE TABLE EMPLOYEES (
    EMPLOYEE_ID NUMBER PRIMARY KEY,
    FIRST_NAME VARCHAR2(50),
    LAST_NAME VARCHAR2(50),
    EMAIL VARCHAR2(100),
    PHONE_NUMBER VARCHAR2(20),
    HIRE_DATE DATE,
    JOB_ID VARCHAR2(10),
    SALARY NUMBER(8,2),
    MANAGER_ID NUMBER,
    DEPARTMENT_ID NUMBER
);

-- 샘플 데이터 삽입
INSERT INTO EMPLOYEES VALUES (100, 'Steven', 'King', 'SKING', '515.123.4567', TO_DATE('17-JUN-2003', 'DD-MON-YYYY'), 'AD_PRES', 24000, NULL, 90);
INSERT INTO EMPLOYEES VALUES (101, 'Neena', 'Kochhar', 'NKOCHHAR', '515.123.4568', TO_DATE('21-SEP-2005', 'DD-MON-YYYY'), 'AD_VP', 17000, 100, 90);
INSERT INTO EMPLOYEES VALUES (102, 'Lex', 'De Haan', 'LDEHAAN', '515.123.4569', TO_DATE('13-JAN-2001', 'DD-MON-YYYY'), 'AD_VP', 17000, 100, 90);
INSERT INTO EMPLOYEES VALUES (103, 'Alexander', 'Hunold', 'AHUNOLD', '590.423.4567', TO_DATE('03-JAN-2006', 'DD-MON-YYYY'), 'IT_PROG', 9000, 102, 60);
INSERT INTO EMPLOYEES VALUES (104, 'Bruce', 'Ernst', 'BERNST', '590.423.4568', TO_DATE('21-MAY-2007', 'DD-MON-YYYY'), 'IT_PROG', 6000, 103, 60);
INSERT INTO EMPLOYEES VALUES (105, 'David', 'Austin', 'DAUSTIN', '590.423.4569', TO_DATE('25-JUN-2005', 'DD-MON-YYYY'), 'IT_PROG', 4800, 103, 60);
INSERT INTO EMPLOYEES VALUES (106, 'Valli', 'Pataballa', 'VPATABAL', '590.423.4560', TO_DATE('05-FEB-2006', 'DD-MON-YYYY'), 'IT_PROG', 4800, 103, 60);

SELECT LEVEL, 
       LPAD(' ', 4*(LEVEL-1)) || e.FIRST_NAME || ' ' || e.LAST_NAME AS "Employee",
       e.EMPLOYEE_ID,
       e.MANAGER_ID,
       e.JOB_ID,
       e.SALARY,
       e.DEPARTMENT_ID
FROM EMPLOYEES e
START WITH e.MANAGER_ID = 0
CONNECT BY PRIOR e.EMPLOYEE_ID = e.MANAGER_ID
WHERE e.DEPARTMENT_ID = 60
ORDER SIBLINGS BY e.SALARY DESC;




- WHERE 절은 계층 구조가 만들어진 후에 적용. => 상위 관리자가 다른 부서에 속해 있어도(ex. 90) 결과에 포함
- ORDER SIBLINGS BY : 이 구문은 같은 레벨의 형제 노드들을 정렬.
  여기서는 각 레벨에서 급여(SALARY)를 기준으로 내림차순 정렬합니다. 예를 들어, LEVEL 4의 Bruce, David, Valli는 모두 같은 상사(Alexander)를 가지고 있으며, 이들은 급여 순으로 정렬됨.
- 최상위노드의 manager_id 는 보통 null 이 된다. 그러나 검색 편의를 위해 특정 값을 넣거나 편의상 컬럼을 추가하기도한다. (ex. IS_ROOT )

- prior 에 명시된 컬럼이 상수로 바뀌고 이를 반대편 컬럼(manager_id) 에 넣고 찾아가게 되므로 해당 컬럼에 인덱스를 생성하는 것이 좋다. 역전개의 가능성이 있기에 반대쪽 컬럼에도 인덱스를 생성하는 것이 좋다. 

 

반응형

'생계 > DA' 카테고리의 다른 글

데이터 모델링 식별자 선정  (0) 2024.10.09
모델링에 대한 생각  (0) 2023.12.27
RDBMS 에서의 관계 라는 것  (0) 2023.12.12
이력 모델  (0) 2023.12.09
엔터티 통합과 분리  (0) 2023.12.09
Posted by 돌고래트레이너
생계/MySQL2024. 12. 24. 16:50

mysql 의 innodb 엔진에서는 테이블 생성시 참조제약조건만 걸고 해당 컬럼에 인덱스를 생성하지 않아도 자동으로 인덱스가 생성이 된다. 

constraint 만 걸고 테이블을 생성하는 것과 명시적으로 키를 생성하는 것의 차이를 알아보자. 

drop table parent;
drop table child_no_idx;
drop table child_idx;


-- parent 테이블 생성 (일반 컬럼 추가)
CREATE TABLE parent (
    id INT NOT NULL PRIMARY KEY,
    name VARCHAR(50),
    email VARCHAR(100),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

-- child 테이블 생성 (제약조건만 명시)
CREATE TABLE child_no_idx (
    id INT NOT NULL PRIMARY KEY,
    parent_id INT,
    name VARCHAR(50),
    email VARCHAR(100),
    description TEXT,
    CONSTRAINT `fk_no_idx_parent_id` FOREIGN KEY (`parent_id`) REFERENCES parent(id)
) ENGINE=InnoDB;

-- child 테이블 생성 (제약조건 + key를 명시)
CREATE TABLE child_idx (
    id INT NOT NULL PRIMARY KEY,
    parent_id INT,
    name VARCHAR(50),
    email VARCHAR(100),
    description TEXT,
    KEY `ix04_child` (`parent_id`),
    CONSTRAINT `fk_idx_parent_id` FOREIGN KEY (`parent_id`) REFERENCES parent(id)
) ENGINE=InnoDB;


-- 인덱스 확인을 위한 쿼리
SHOW INDEX FROM child_no_idx;


SHOW INDEX FROM child_idx;

참조제약조건이 걸려있으면 인덱스를 생성하지 않아도 자동으로 인덱스가 (제약조건 이름으로) 생성이 되었다. 

이제 세컨더리 인덱스를 아래와 같이 추가해보자. 

create index ix01_child on child_no_idx(name, parent_id);
create index ix02_child on child_no_idx(parent_id, name);

제약조건 이름으로 자동 생성되었던 인덱스가 사라졌다. 

참조 제약조건 컬럼(parent_id) 을 선두로 하는 인덱스가 명시적으로 생기면 자동 생성된 인덱스가 사라진다.  

 

두번째 명시적으로 key 를 만들었던 경우를 비교해보자. 

세컨더리 인덱스를 동일하게 추가해보자. 

create index ix01_child on child_idx(name, parent_id);
create index ix02_child on child_idx(parent_id, name);

사라지지 않고 남아있다.  

물론 ix02_child 인덱스가 parent_id 컬럼을 포함하므로 ix04_parent_id 인덱스는 삭제가 되어도 상관이 없다. 

다만 (제약조건으로 인해) 자동 생성된 인덱스는 자동 삭제가 될수도 있다는 것을 유의해야하고, 이를 인지 하지 않은 상태에서 인덱스를 추가할 경우 의도치 않게 삭제될수 있으니 무조건 명시적으로 key 를 만드는 것이 좋다. 

반응형
Posted by 돌고래트레이너
생계/OS2024. 12. 13. 00:03

IOPS와 throughput은 데이터베이스 및 스토리지 시스템의 성능을 측정하는 중요한 지표이다.


IOPS (Input/Output Operations Per Second)

초당 처리할 수 있는 읽기/쓰기 작업의 수를 나타냄
작은 파일들에 대한 빈번한 접근이 필요한 경우에 중요한 지표
데이터에 대한 빠른 접근 및 처리가 필요한 환경에서 중요

Throughput (처리량)

초당 처리할 수 있는 데이터의 크기를 측정. 주로 메가바이트 단위로 표현
큰 파일들을 주로 다루고 데이터 처리 작업이 많지 않은 경우에 중요한 지표
한 번에 큰 용량의 파일을 읽어야 할 때 중요

계산식

IOPS x I/O size = Throughput
예: 16,000 IOPS × 64 KiB = 1,024 MiB/s (Throughput)

반응형
Posted by 돌고래트레이너
생계/Oracle2024. 12. 11. 01:19

오라클에서 SQL 의 처리과정 

https://docs.oracle.com/en/database/oracle/oracle-database/19/tgsql/sql-processing.html#GUID-873A7B2C-CD17-428A-8AE2-5B08906E45FB

사용자가 SQL 을 실행하면 아래 1~ 3 까지의 파싱 단계를 거치게 된다. 

 1. syntax check : 문법적 오류 체크 (ex. select * form tab_a )

 2. semantic check : 존재하지 않는 테이블 조회 등

 3. shared pool check : 동일한 sql 이 shared pool 에 캐싱되어 있는지 확인 

이 과정을 거쳐 SQL 이 캐싱되어 있지 않는 것으로 확인되면 (library cache miss) 

4. 실행계획 생성 단계를 거쳐 

5. 최종적으로 실행을 하게 된다. 

이때 실행계획 생성과정에서 library cache, data dictionary cache 에 반복적으로 접근하고 이 과정에서 

latch 라는 lock 보다는 가벼운 잠금장치를 수없이 획득하는 과정을 거친다. 

 

소프트 파싱 vs 하드 파싱

소프트 파싱 (Soft Parsing) 이라는 것은 이미 만들어진 실행계획을 캐시에서 찾아 재사용하는 과정이다. 

Shared Pool의 Library Cache에 저장된 SQL 실행 계획을 공유하여 최적화 과정을 생략한다.
실행계획 생성과정이 cpu 를 많이 소모하는 과정이기 때문에 하드 파싱에 비해 더 빠르고 리소스를 절약할 수 있다.

하드 파싱 (Hard Parsing) 캐시에 SQL 이 존재하지 않아 (library cache miss) 새로운 실행 계획을 생성해야 할 때 발.

최적화 및 로우 소스 생성 단계까지 모두 거친 후에 SQL 이 실행된다. 

소프트 파싱의 이점과 한계

소프트 파싱은 실행 계획을 반복적으로 생성하는 오버헤드를 줄여 성능을 향상 시켜주어 이롭지만( 특히 OLTP 환경에서 동시 접속자가 많을 때 효과적 ) 항상 최선의 선택은 아니다.

사용자 입력값을 바인드 변수 처리하면 같은 SQL ID 로 처리되어 소프트 파싱으로 처리되는 비율이 높아지지만 

SQL 최적화 시점에 컬럼의 히스토그램을 사용하지 못해 실행 계획이 고정 되고 실제 데이터의 분포도가 플랜에 적용이 안되는 경우가 생긴다. 

 

바인드 Peeking의 역효과 예시


다음과 같은 테이블과 쿼리가 있다고 가정해봅시다:
sql
SELECT * FROM 직원 WHERE 부서 = :dept

이 테이블에서 '영업부'는 전체 직원의 50%를 차지하고, 나머지 부서들은 각각 5% 미만의 직원을 가지고 있습니다.
첫 실행 시 :dept에 '인사부'가 바인딩되었다면:
옵티마이저는 인덱스 스캔을 선택합니다.
이 실행 계획이 캐시에 저장됩니다.
이후 '영업부'로 쿼리를 실행하면:
캐시된 실행 계획(인덱스 스캔)을 사용합니다.
하지만 영업부는 데이터의 50%를 차지하므로, 풀 테이블 스캔이 더 효율적일 수 있습니다.
이로 인해 '영업부' 쿼리의 성능이 크게 저하될 수 있습니다1.

소프트 파싱 한계에 대한 대안

1. 힌트 사용:
특정 쿼리에 대해 옵티마이저 힌트를 사용하여 원하는 실행 계획을 강제
SELECT /*+ FULL(직원) */ * FROM 직원 WHERE 부서 = :dept

2. 아웃라인 사용:
특정 쿼리에 대한 실행 계획을 고정
CREATE OUTLINE 직원_부서_조회 FOR
SELECT * FROM 직원 WHERE 부서 = :dept;

3. 적응적 커서 공유 활용:
Oracle 11g 이상에서는 적응적 커서 공유를 통해 바인드 변수 값에 따라 다른 실행 계획을 사용할 수 있다

4. 특정 SQL의 소프트 파싱 방지
SELECT /*+ NO_SHARED_CURSOR */ * FROM 직원 WHERE 부서 = :dept

5. CURSOR_SHARING 파라미터 조정:

세션 레벨에서 CURSOR_SHARING을 EXACT로 설정, 해당 세션의 모든 쿼리에 대해 소프트 파싱을 방지
ALTER SESSION SET CURSOR_SHARING = EXACT;


반응형
Posted by 돌고래트레이너
생계/MySQL2024. 11. 25. 15:28

mysql 의 auto_increment 특징 과 주의점들을 알아보자 


# AUTO_INCREMENT의 특징, 최대 값

1) 자동 증가: 새로운 레코드가 삽입시 자동으로 고유한 숫자를 생성. 주로 기본 키로 사용, 각 행의 고유성을 보장
2) 초기값 및 증가값 설정 가능: 기본적으로 1부터 시작하며, 각 행이 추가될 때마다 1씩 증가. 
3) 데이터 타입 제한: 주로 INT 타입으로 설정, 데이터 타입에 따라 최대값이 제한됩니다. 예를 들어, INT의 최대값은 약 21억입니다
4) 연속성: 삭제된 행의 ID는 재사용되지 않고 건너뛴다.

* mysql 에서 innodb 를 엔진으로 사용할때 auto_increment 컬럼을 pk 사용하는 것이 적절한가?

innodb 사용시 pk 의 선정


# 타입 별 최대 값

데이터 타입 SIGNED 범위 UNSIGNED 범위
TINYINT -128 to 127 0 to 255
SMALLINT -32,768 to 32,767 0 to 65,535
MEDIUMINT -8,388,608 to 8,388,607 0 to 16,777,215
INT -2,147,483,648 to 2,147,483,647 0 to 4,294,967,295 (42억)
BIGINT -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 0 to 18,446,744,073,709,551,615
(1800경, 18.44 엑사(E))

 


# 현재 값 확인하기

방법 1) SHOW TABLE STATUS

SHOW TABLE STATUS WHERE Name = '테이블명';

테이블의 상태 정보를 반환하며, 다음 AUTO_INCREMENT 값을 포함하여 테이블의 엔진, 행 수, 평균 행 길이 다양한 메타데이터를 제공

방법 2) INFORMATION_SCHEMA.TABLES

SELECT AUTO_INCREMENT 
   FROM INFORMATION_SCHEMA.TABLES 
 WHERE TABLE_SCHEMA = '데이터베이스명' 
   AND TABLE_NAME = '테이블명'
;

INFORMATION_SCHEMA.TABLES 뷰를 통해 특정 데이터베이스와 테이블에 대한 정보를 쿼리

방법 3) SELECT MAX() 

SELECT MAX(컬럼명) + 1 AS next_auto_increment FROM 테이블명;

현재 존재하는 최대 값을 기반으로 다음 AUTO_INCREMENT 값을 추정
데이터가 삭제되거나 수동으로 삽입된 경우 정확하지 않을 수 있다.

 

* 이전 버전에서는 auto_increment 값을 메모리에서 관리했지만(서버 재시작시 초기화), 8.0부터는 디스크에 저장하여 영속성을 보장한다.

반응형
Posted by 돌고래트레이너
생계/MySQL2024. 11. 19. 16:39

mysql 파티션 테이블 

# 일반테이블의 파티션 전환시 유의점 
1. 인덱스 제약:
   - MySQL의 파티션 테이블에서는 모든 인덱스가 로컬 인덱스로 처리된다.
   - 글로벌 인덱스를 지원하지 않으므로, 기존 인덱스 구조를 재검토해야 함.

2. 유니크 키와 프라이머리 키 제약:
   - 파티션 키는 모든 유니크 인덱스(프라이머리 키 포함)의 일부 또는 모든 칼럼을 포함해야 함. 아닐경우 에러남
   - 기존 테이블의 키 구조가 이 요구사항을 충족하는지 확인 필수 

3. 외래 키 제약:
   - 파티션 테이블에는 외래 키를 설정 불가 (성능, 관리적 측면의 설계결정)
   - 기존 테이블에 외래 키가 있다면 이를 제거하거나 대체 방안을 마련 필요.

4. 파일 제한:
   - 파티션 테이블은 각 파티션마다 별도의 파일을 사용하므로, 서버의 open-files-limit 설정을 적절히 조정필요.

5. 성능 고려:
   - 파티션 개수가 많아질수록 오히려 성능이 저하될 수 있다.
   - 특히 INSERT 작업의 경우, 파티션 테이블이 일반 테이블보다 느려질 수 있다.

6. 잠금 처리:
   - 파티션 테이블에 쿼리 실행 시 모든 파티션에 대해 잠금이 걸린다.
   - 이는 동시성 처리에 영향을 줄 수 있으므로 주의 필요.

7. 파티션 키 선택:
   - 효과적인 파티션 프루닝을 위해 적절한 파티션 키를 선택해야 함.
   - 주로 조회 조건에 자주 사용되는 칼럼을 파티션 키로 선택하는 것이 유리 

8. 데이터 마이그레이션:
   - 기존 데이터를 새로운 파티션 구조로 마이그레이션하는 과정에서 서비스 중단이 필요한지 확인 필요
   - 대량의 데이터 이동이 필요하므로 충분한 시간과 리소스를 확보해야 함.

9. 쿼리 최적화:
   - 기존 쿼리들이 파티션 구조에서도 효율적으로 동작하는지 검토, 필요시 최적화 필요.

이러한 점들을 고려하여 신중하게 파티션 전환을 계획하고 실행해야 한다. 또한 전환 전후로 충분한 테스트를 수행하여 성능과 기능에 문제가 없는지 확인해야 합니다.
 
# 파티션 테이블 샘플 스크립트 
-- 1. 날짜 기반 레인지 파티션 테이블 생성
CREATE TABLE sales (
    id INT AUTO_INCREMENT,
    sale_date DATE NOT NULL,
    customer_id INT,
    amount DECIMAL(10,2),
    PRIMARY KEY (id, sale_date)
)
PARTITION BY RANGE (YEAR(sale_date)) (
    PARTITION p2021 VALUES LESS THAN (2022),
    PARTITION p2022 VALUES LESS THAN (2023),
    PARTITION p2023 VALUES LESS THAN (2024),
    PARTITION p2024 VALUES LESS THAN (2025),
    PARTITION future VALUES LESS THAN MAXVALUE
);

-- 2. 파티션 관리: 새 파티션 추가
ALTER TABLE sales ADD PARTITION (PARTITION p2025 VALUES LESS THAN (2026));

-- 3. 파티션 최적화
ALTER TABLE sales OPTIMIZE PARTITION p2021, p2022, p2023;

-- 4. 특정 파티션 데이터 삭제
ALTER TABLE sales TRUNCATE PARTITION p2021;

-- 5. 파티션 삭제
ALTER TABLE sales DROP PARTITION p2021;

-- 6. 파티션 분할
ALTER TABLE sales REORGANIZE PARTITION p2023 INTO (
    PARTITION p2023_h1 VALUES LESS THAN ('2023-07-01'),
    PARTITION p2023_h2 VALUES LESS THAN (2024)
);
-- maxvalue 파티션 분할 
ALTER TABLE sales
REORGANIZE PARTITION future INTO (
    PARTITION p2025 VALUES LESS THAN (2026),
    PARTITION future VALUES LESS THAN MAXVALUE
);

-- 7. 파티션 정보 확인
SELECT PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTH
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'your_database_name' AND TABLE_NAME = 'sales';

-- 8. 파티션을 고려한 쿼리 예시
SELECT * FROM sales PARTITION (p2023)
WHERE sale_date BETWEEN '2023-01-01' AND '2023-12-31';

 

반응형
Posted by 돌고래트레이너
생계/MySQL2024. 11. 19. 13:17

MySQL의 innodb_read_only와 read_only 파라미터는 비슷한 목적으로 사용되지만 몇 가지 중요한 차이점이 있다

1. 적용 범위:
   - innodb_read_only: InnoDB 스토리지 엔진을 사용하는 테이블에만 적용됩니다.
   - read_only: 모든 스토리지 엔진에 적용됩니다.

2. 권한 처리:
   - innodb_read_only: 모든 사용자(SUPER 권한 포함)의 쓰기 작업을 금지합니다.
   - read_only: SUPER 권한(또는 CONNECTION_ADMIN)을 가진 사용자는 여전히 쓰기 작업이 가능합니다.

3. 설정 변경:
   - innodb_read_only: 서버 시작 시에만 설정 가능한 정적 변수입니다.
   - read_only: 동적 변수로, 서버 운영 중에도 변경 가능합니다.

4. 작업 제한:
   - innodb_read_only: InnoDB 관련 모든 쓰기 작업을 금지합니다.
   - read_only: 일반적인 데이터 변경 작업을 금지하지만, TEMPORARY 테이블 작업이나 복제 관련 작업 등은 허용합니다.

5. 사용 목적:
   - innodb_read_only: 주로 읽기 전용 미디어에서 MySQL을 실행하거나, 데이터 무결성을 위해 사용됩니다.
   - read_only: 주로 복제 설정에서 슬레이브 서버를 읽기 전용으로 만들기 위해 사용됩니다.

6. 시스템 테이블 영향:
   - innodb_read_only: mysql 시스템 데이터베이스의 InnoDB 테이블에도 영향을 미칩니다.
   - read_only: 일부 시스템 작업(예: FLUSH TABLES WITH READ LOCK)은 여전히 허용됩니다.

따라서 innodb_read_only는 더 엄격한 읽기 전용 모드를 제공하며, read_only는 일반적인 운영 상황에서 더 유연한 읽기 전용 모드를 제공합니다.

반응형
Posted by 돌고래트레이너
생계/MySQL2024. 11. 13. 18:22

mysql 에서 table 을 복사하는 몇가지 방법 및 특징을 알아보자

1. CTAS 

 CREATE TABLE NEW_TAB  AS  SELECT * FROM OLD_TAB ;

 - 테이블 구조와 모든 데이터를 복사

 - 인덱스, 기본 키, 외래 키, auto_increment 속성 등은 복사되지 않음

 - charset, collate 는 default 속성을 따라감

2. LIKE 

 CREATE TABLE NEW_TAB LIKE OLD_TAB ;

- 원본 테이블의 구조(컬럼, 인덱스, 제약 조건 등)를 그대로 복사

- FK 제약조건은 복사가 되지 않는다. 따로 추가해야 함

SELECT CONCAT( 'ALTER TABLE `B`.`', TABLE_NAME, '` ADD CONSTRAINT `', CONSTRAINT_NAME, '` ', 'FOREIGN KEY (`', COLUMN_NAME, '`) ', 'REFERENCES `B`.`', REFERENCED_TABLE_NAME, '` (`', REFERENCED_COLUMN_NAME, '`);' ) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = 'A' AND REFERENCED_TABLE_SCHEMA IS NOT NULL;

3. SHOW CREATE TABLE 

 SHOW CREATE TABLE OLD_TAB; => DDL 추출해서 생성

4. 덤프로 복사

테이블이 여러개이면 dump& load 가 최고. 테이블 구조, 데이터, 인덱스, 외래 키 제약 조건이 복사된다.

mysqldump -u root -p A > A_schema_backup.sql

CREATE DATABASE B;

mysql -u root -p B < A_schema_backup.sql

반응형
Posted by 돌고래트레이너
생계/NoSQL2024. 11. 12. 19:01

Remote Dictionary Server

1. cache
cache 구현 방법 : memcached, redis, local memory cache 

 cache 전략
 - 읽기 전략
1) look aside : cache 에 없으면 db조회 
  장) 캐시 문제생기면 db 로 위임
  단) 캐시,db간 정합성 유지 어려움 
 
2) read through : 항상 캐시를 통해 
  장) 캐시,db간 정합성 유지 
  단) 캐시 죽으면 장애 
 
 - 쓰기 전략
1) write around : 캐시 우회해서 db에 바로 write  
   장) 성능 이점
   단) 캐시, db간 정합성 유지 어려움
2) write back : 캐시에 미리 write, 나중에 db에 모아서 write  
   장) 쓰기 비용 줄임
   단) 캐시 data loss 가능성

3) writh through : 항상 캐시 먼저 write , 그리고 db에 write  
장) 정합성 유지
단) 항상 두번 쓰는 성능 불리 

2. redis 

redis 용도 : 캐싱, 임시작업 큐, 실시간 채팅, 메시지 브로커 

 특징 
 1) performance
    : 메모리에 저장, get/set 초당 10만 tps
 2) single thread
   : 한번에 하나의 명령만 처리. race condition 발생 X
 3) data structure
   : 다양한 자료구조 제공 
 4) persistence 
   : 메모리 저장 데이터를 디스크 영속화. 복구 가능 
  - RDB (Redis Database Backup) 
   => 특정 간격 메모리 데이터 스냅샷 
  장) 압축,저장 -> 크기 작고 로딩/복구 빨라
  단) 백업 중 다운 되면 최신 데이터 유실 가능성 
 - AOF (Append Only File) 
 => dml 실행시 log파일에 기록 
  장) 실시간 데이터 백업, 데이터 손실 거의 없음
  단) 명령실행 모두 기록 -> 파일크기, 복원시 긴 시간
 

반응형
Posted by 돌고래트레이너