MySQL/MariaDB sql_mode 설정 변경으로 NULL 데이터 처리하기

 

·       Version : MySQL 5.7

 

MS SQL Server에서 BCP 이용하여 데이터를 구분형식의 텍스트 파일로 내려받고 MySQL에서는 Bulk load(LOAD DATA INFILE) 사용하여 데이터를 복원할때 아래와 같은 에러가 지속적으로 발생하였다.

Error Code: 1366. Incorrect decimal value …

 

문제는 Decimal 컬럼에 NULL값을 입력할때 MySQL 유효성 문제로 에러가 발생한 것이다. 해당 컬럼은 NULL 허용 컬럼임에도 불구하고 지속적으로 동일한 문제가 발생하여, 해결 방법을 찾아본 결과 아래와 같은 sql_mode 변경으로 해결할 있었다.

SET SESSION sql_mode = ''

 

Server SQL Mode MySQL 지원해야 하는 SQL 구문과 수행해야하는 데이터의 유효성 검사의 종류를 정의한다. MySQL 서버는 이러한 모드를 클라이언트에 개별적으로 적용할 있다. 운영중에 모드를 변경하려는 경우, SET 명령을 사용할 수있으며, GLOBAL 또는 SESSION  변수를 사용할 있다. GLOBAL 변수의 경우 SUPER 권한이 필요하며, 설정 이후 모든 클라이언트의 작동에 영향을 준다. SESSION 현재 클라이언트에만 영항이 있다. 현재 설정된 sql_mode 값을 확인하려면 아래 스크립트를 실행한다.

SELECT @@GLOBAL.sql_mode;

SELECT @@SESSION.sql_mode;

 

 

. MySQL 5.7 경우 기본SQL 모드는 아래와 같다.

ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, and NO_ENGINE_SUBSTITUTION

 

이번 해결은 유효성 검사를 비활성화 하여 해결하였지만 Sql_mode 변경은 시스템 환경을 변경하는것으로 반드시 알고 사용해야 하며 다른 서비스에 영향이 없는지 반드시 검토가 필요하다.  자세한 내용은 아래 링크를 참고 한다.

·       Server SQL Mode : https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html

 

 

 [참고자료]

·       Server SQL Mode : https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html

·       FAQ : Server SQL Mode : https://dev.mysql.com/doc/refman/5.7/en/faqs-sql-modes.html

 

 

2019-07-05 / 강성욱 / http://sungwookkang.com

 

MySQL, MySQL sql_mode, 유효성 검사, 벌크로드, NULL Exception, NULL 값처리, 데이터 마이그레이션, LOAD DATA INFILE

MySQL/MariaDB Timezone 설정 확인

 

·       Version : MySQL 5.7, Docker

 

MySQL/MariaDB 운영할때, 타임존에 대해서 알아본다. 아래 스크립트는 현재 데이터베이스의 타임존을 확인한다. 타임존이 SYSTEM 으로 표시되면 별도의 타임존 설정이 되어 있지 않다는 뜻이며 시스템의 타임존을 사용하겠다는 뜻이다.

SELECT @@GLOBAL.time_zone, @@SESSION.time_zone, @@system_time_zone;

 

 

데이터베이스 설정에서 default-time-zone 변경 방법은 my.ini (my.cnf)에서 [mysqld] 영역에 타임존을 추가한다. 아래 스크립트는KST 타임존을 설정하였으며 스크립트 적용 MySQL 서비스 재시작이 필요하다.

[mysqld]

default-time-zone='+9:00'

 

다른 방법으로는 현재 서비스 상태에서 글로벌, 또는 세션 변수의 값을 명시적으로 설정할 있다. 방법은 서비스를 재시작 하지 않아도 된다.

SET GLOBAL time_zone='timezone;

SET time_zone='timezone;

 

어플리케이션에서 연결시에도 타임존을 지정할 있다. 경우 세션으로 작동한다. JDBC URL 추가하는 방법은 아래 코드를 참고 한다.

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">

  <property name="driverClassName" value="com.mysql.jdbc.Driver"/>

  <property name="url" value="jdbc:mysql://127.0.0.1:3306/ db?serverTimezone=UTC" />

  <property name="username" value="admin"/>

  <property name="password" value="admin"/>

</bean>

 

Timezone 값은 여러 가지 포맷으로 사용할 있으며 대소문자 구분이 없다.

·       SYSTEM MySQL 시스템의 타임존과 동일한 설정을 사용

·       ‘+9:00’ 또는 ‘-6:00’ 같이 GTM/UTC 기준 Offset 사용

·       US/Eastern, Asia/Seoul 같은 named timezone 사용

 

named timezone 형태의 값을 사용하려면  “mysql” 데이터베이스에 “time_zone”, “time_zone_name”, “time_zone_transition”, “time_zone_transition_type”, “time_zone_leap_second” 테이블을 참조하는데 실제 테이블은 빈테이블이기 때문에 사용자가 데이터를 입력해주어야 한다. 타임존 데이터는 아래 링크에서 정보를 다운로드 받아 스크립트를 실행한다. 스크립트를 살펴보면 타임존 정보를 확인할 있다.

·       https://dev.mysql.com/downloads/timezones.html

 

[참고자료]

·       https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html

 

2019-06-12 / 강성욱 / http://sungwookkang.com

MySQL, MySQL Timezone, 타임존, DB time, time_zone, time_zone_name, time_zone_transition, time_zone_transition_type, time_zone_leap_second, named timezone

 

 Redis Memory LFU(Least Frequently Used) 캐시

 

·       Version : Redis 4.0

 

Redis 4.0 부터 제공되는 LFU 알고리즘 캐시는 자주 참조되는 데이터만 배치하고 그렇지 않은 데이터들은 메모리로부터 제거하여 자주 사용되는 데이터들이 메모리에 배치되도록하는  알고리즘이다. LRU 알고리즘은 최근에 액세스 했지만 실제로는 거의 요청하지 않는 항목에 대해서도 메모리에 보관하고 자주 요청되는 키에 대해서는 만료가 되기 때문에 의도하지 않은 성능이 나타날 수도 있다.

LFU Approximated LRU 유사하다. 모리스 카운터라고 하는 확률적 카운터를 사용하여 개체의 액세스 빈도를 계산하고 감쇠 기간과 결합하여 시간이 지남에 따라 카운터가 감소한다. 알고리즘은 액세스 패턴의 변화를 확인하고 과거에 액세스가 있었지만 자주 액세스되지 않는 키는 삭제 후보로 선정한다. 이러한 방법은 LRU에서 발생하는것과 유사하게 샘플링된다. 그러나 LRU 달리 LFU에는 특정 조정가능한 매개변수가 있다. 예를들어 이상 객체에 액세스하지 않게 되면 랭크를 얼마나 빨리 감소 시킬것인지 설정할 있다. Redis 4.0 기본적으로 아래와 같이 구성된다.

·       100만건의 요청에 카운터를 포화시킨다.

·       카운터를 1분마다 감쇠한다.

 

카운터 범위 조정은 Redis.conf 파일에 아래와 같이 관련 파라메터를 수정한다.

·       lfu-log-factor 10 (기본값 10)

·       lfu-decay-time 1

lfu-decay-time 변수값은 (minute) 사용되며 0으로 설정할 경우 항상 카운터를 스캔할 때마다 카운터를 감소시킨다.

lfu-log-factor 범위는 0-255이며,  factor 높을수록 최대 값에 도달하기 위해 많은 액세스가 필요하다. Hits 값은 사용자가 메모리로부터 데이터를 재참조한 값으로 높을 수록 좋다. 아래 표에서는 팩터가 10일때 1M 이상의 힛트가 발생하는 경우 가장 이상적인 것을 확인할 있다..

factor

100 hits

1000 hits

100k hits

1M hits

10M hits

0

104

255

255

255

255

1

18

49

255

255

255

10

10

18

142

255

255

100

8

11

49

143

255

 

 

[참고자료]

·       https://redis.io/topics/lru-cache

·       Approximate counting algorithm : https://en.wikipedia.org/wiki/Approximate_counting_algorithm

 

2019-06-06 / Sungwook Kang / http://sungwookkang.com

 

Redis, Redis Architecture, 레디스 메모리, Redis LFU, LFU 알고리즘, Least Frequently Used, 레디스 메모리 공간 확보, 레디스 메모리 제거

'NoSql, MemoryDB' 카테고리의 다른 글

NoSQL 특징및 분류  (0) 2020.06.09
CAP 이론  (0) 2020.06.08
Redis Memory LRU(Least Recently Used) 캐시  (0) 2019.06.04
Redis Memory 정보  (0) 2019.05.21
Redis Architecture  (0) 2019.05.18

 Redis Memory LRU(Least Recently Used) 캐시

 

·       Version : Redis 3.2.100 (Windows)

 

Redis에서 캐시로 사용되는 알고리즘으로 LRU(Least Recently Used) 사용한다.  LRU 알고리즘은 최근에 사용된 데이터들은 재사용이 가능성이 높다고 판단하여 계속해서 메모리에 상주 시킬수 있도록 재배치 하는 작업이다.  LRU 알고리즘으로 Redis 서버 인스턴스를 운영하기 위해서는CONFIG SET 명령어 또는  redis.conf 파일에서 아래 파라메터를 수정한다.

·       maxmemory <bytes>

·       maxmemory-samples 5

maxmemory 파라메터는 Redis 서버에 할당할 있는 최대 메모리 크기이며, 값을 0 설정할 경우 최대 메모리 한계가 없어진다. 32 bit 시스템에서는 암시적으로 메모리 제한이 3GB 사용한다.

maxmemory-samples 파라메터는 LRU 알고리즘에서 퇴거(eviction) 검사할 샘플 이다.

 

Redis 메모리의 상주 데이터를 삭제하는 종류는 가지가 있으며 memory-policy  구문을 사용하여 아래와 같은 정책을 적용할 있다.

·       noeviction : 메모리 제한에 도달한 상태에서 클라이언트가 많은 메모리를 사용하는  명령을 실행하려고 오류를 리턴한다. (대부분 쓰기 명령 DEL 명령시 발생한다.)

·       allkeys-lru : 가장 최근에 사용하지 않는 (LRU) 먼저 퇴거(eviction)하여 새로운 데이터를 위한 공간을 확보한다.

·       volatile-lru :  가장 최근에 사용되지 않은 (LRU) 먼저 퇴거(evict)하려고 시도하지만 만료 세트가 있는 키만 퇴거하여 새로운 데이터 공간을 확보한다.

·       allkeys-random : 세이터를 추가할 공간을 만들기 위해 임의로 키를 퇴거(evict)한다.

·       volatile-random :   데이터를 추가하기위한 공간을 만들기 위해 무작위로 키를 퇴거(evict)하지만 만료 세트가 있는 키만 제거한다.

·       volatile-ttl : 만료 세트가 있는 키를 제거하고 TTL(Short Time to Live)키를 제거하여 새로운 데이터를 추가 공간을 확보한다.

 

volatile-lru, volatile-random volatile-ttl 정책은 필수 구성요소와 일치하는 키가 없으면 아무런 행동을 하지 않는다. 올바른 퇴거 정책을 수립하기 위해서는 Redis INFO 정보를 모니터링하여 정책에 반영할 있도록 한다.

·       요청이 많으며 과거 데이터를 자주 사용하지 않는다면 allkeys-lru  정책을 사용한다.

·       모든 키가 연속적으로 스캔되는 순환 액세스가 있거나 배포가 균일할 것으로 예상되는 경우 (모든 요소는 동일한 확률로 액세스 가능성이 높음) allkeys-random 사용한다.

·       캐시 개체를 만들 다른 TTL 값을 사용하여 만료 기간이 좋은 항목에 대한 힌트를 Redis 제공하려면 volatile-ttl 사용한다.

 

volatile-lru volatile-random 정책은 캐싱 영구 집합에 대한 단일 인스턴스를 사용하려는 경우 유용하다. 그러나 일반적으로 이러한 문제를 해결하기 위해 개의 Reids 인스턴스를 실행하는 것이 좋다. 또한 키에 만료를 설정하면 메모리가 낭비되므로 allkeys-lru 같은 정책을 사용하면 메모리가 부족할 키가 만료되도록 설정할 필요가 없기 때문에 많은 메모리가 효율적으로 운영된다.

 

Redis LRU 알고리즘은 정확한 구현이 아니다. 이뜻은 Redis 퇴출을 위한 최선의 후보, 과거에 가장 많이 액세스 액세스를 선택할 없음을 의미한다. 대신 LRU 알고리즘의 근사치를 실행하거나 소수의 키를 샘플링 하고 샘플링된 중에서 가장 오래된 액세스 시간(가장 오래된 액세스 시간) 제거하려고 시도한다. 그러나 Redis 3.0 이후 알고리즘은 개선 퇴거 후보자를 확보하기 위해 개선되었다. 이로 인해 알고리즘의 성능이 향상되어 실제 LRU 알고리즘의 동작을 보다 자세히 근사할 있게 되었다.

Redis 진정한 LRU 구현을 사용하지 않는 이유는 많은 메모리가 필요하기 때문이다. 그러나 근사값은 Redis 사용하는 응용프로그램과 거의 같다. 다음은 Redis에서 사용한 LRU 근사값과 실제 LRU 비교하는 방법을 그래픽으로 비교한 것이다.

그림에서 연한 회색은 퇴거된 영역이며, 회색은 퇴거되지 않은 대상이다. 녹색은 추가된 객체이다. 시뮬레이션에서 지수법 접근 패턴을 사용하여 실제  LRU Redis 근사값 간의 차이가 미미하거나 존재하지 않는다는 것을 발견했다. 그러나 실제 LRU 근사하게 비교하고 캐시 미스 비율에 차이가 있는지 확인하기 위해 가지 추가 CPU 사용량을 희생시켜 샘플 크기를 10으로 늘릴 있다.

 

 

[참고자료]

https://redis.io/topics/lru-cache

 

2019-06-03 / Sungwook Kang / http://sungwookkang.com

 

Redis, Redis Architecture, 레디스 메모리, Redis LRU, LRU 알고리즘, Least Recently Used, 레디스 메모리 공간 확보, 레디스 메모리 제거

'NoSql, MemoryDB' 카테고리의 다른 글

CAP 이론  (0) 2020.06.08
Redis Memory LFU(Least Frequently Used) 캐시  (0) 2019.06.07
Redis Memory 정보  (0) 2019.05.21
Redis Architecture  (0) 2019.05.18
Redis 데이터 타입 – Geo  (0) 2019.05.15

 Redis Memory 정보

 

·       Version : Redis 3.2.100 (Windows)

 

Redis에서 info명령은 서버의 각종 통계 상태를 보여준다. 다양한 매개 변수를 사용하여 특정 정보를 확인할 있으며 이번 포스트에서는 메모리 관련 정보를 확인해본다.

 

Redis 접속하여 Redis info 명령을 실행하면 메모리 관련 사용 정보를 반환한다.

info memory

 

 

·       *_human 값은 동일 항목의 byte 값을 Kbyte 변환하여 나타낸

Info linst

Comments

used_memory

Redis 서버에 현재 할당된(libc, jemalloc, tcmalloc ) 메모리 크기 (byte)

used_memory_rss

운영체제에서 Redis 할당한 byte .

used_memory_peak

Redis 할당되었던 최대 메모리 크기 (byte)

used_memory_peak_perc

used_memory used_memory_peak 백분율

used_memory_overthread

사용자 메모리 크기에 대한 overthread

used_memory_startup

최초 할당되었던 Redis 메모리 크기 (byte)

used_memory_dataset

사용자 데이터가 저장된 메모리 크기 (byte)

used_memory_dataset_perc

Net 메모리 사용량에서 used_memorydataset 백분율. (used_memory 에서 used_memory_startup 뺀값)

total_system_memroy

시스템 메모리 크기 (byte)

used_memory_lua

Lua 엔진에 의해 사용된 메모리 크기 (byte)

maxmemory

Maxmemory 파라메터에 설정된 메모리 크기 (byte)

maxmemory_policy

Maxmemory_policy 파라메터에 설정된 메모리 크기 (byte)

mem_fragmentation_ratio

메모리 단편화 상태비율

mem_allocator

컴파일시에 할당된 메모리

active_defrag_running

조각 모음이 활성 상태인지 나타내는 플래그

lazyfree_pending_objects

할당 해지 대기 중인 오브젝트

 

이상적으로 used_memory_rss 값은 used_memory 보다 약간 높아야 한다. rss >> 사용하면 mem_fragmemtation_ratio 검사하여 메모리 조각화(내부 또는 외부) 있는지 확인할 있다.  >> rss 사용하면 Redis 메모리의 일부가 운영체제에 스왑 아웃을 되었다는 것을 의미한다. 뜻은 지연이 있다는 것을 의미한다.

 

Redis 메모리 페이지에 매핑되는 할당 방식을 제어할 없으므로 높은 used_memory_rss 메모리 사용이 급증하여다는 것을 의미한다. Redis 메모리를 해제하면 메모리는시스템에 메모리를 반환하거나 하지 않을 있다. 따라서 운영체제에서 보고한 used_ memory값과 메모리 소비간에 불일치가 있을 있다. used_memory_peak  값은 일반적으로 지점을 확인하는데 유용하다.

 

서버의 메모리에 대한 추가 정보는 memory stats 명령과 memory doctor 참조하여 확인할 있다.

 

 

[참고자료]

https://redis.io/commands/INFO

 

2019-05-20 / Sungwook Kang / http://sungwookkang.com

 

Redis, Redis Architecture, 레디스 메모리, 레디스 메모리 사용량, 메모리 모니터링, Redis, info memory

'NoSql, MemoryDB' 카테고리의 다른 글

Redis Memory LFU(Least Frequently Used) 캐시  (0) 2019.06.07
Redis Memory LRU(Least Recently Used) 캐시  (0) 2019.06.04
Redis Architecture  (0) 2019.05.18
Redis 데이터 타입 – Geo  (0) 2019.05.15
Redis 데이터 타입 – bit  (0) 2019.05.10

 Redis Architecture

 

·       Version : Redis 3.2.100 (Windows)

 

아래 그림은 Redis Server Architecture 이며, 크게 3가지 영역인, 메모리, 파일, 프로세스 영역으로 구성되어 있다.

 

[메모리 영역]

·       Resident Area (Working Set) : 사용자가 Redis 서버에 접속해서 처리하는 모든 데이터가 가정 먼저 저장되는 영역이며 실제 작업이 수행되는 영역.

·       Data Structure : Redis 운영하기 위한 다양한 정보를 저장하고 관리하기 위한 영역.

 

[파일 영역]

·       AOF 파일 : 메모리에 저장된 사용자 데이터를 파일에 기록하는 영역 (스냅샷 데이터)

·       DUMP 파일 : 소량의 데이터를 일시적으로 저장할때 사용하는 영역

[프로세스 영역]

·       Server Process : redis-server.exe 또는 redis-sentinel.exe  실행 코드에 의해 활성화되는 프로세스이며, Redis 인스턴스 관리 사용자 요청 작업을 처리한다. 4개의 멀티 스레드로 구성된다.

ü  Main Thread : Redis 서버에서 수행되는 대부분의 명령어와 이벤트 처리

ü  BIO-Close-FILE  : AOF(Append Only File) 데이터를 Rewrite 할때 기존 파일은 Close 하고 새로운 AOF 파일에  Write 사용.

ü  BIO-AOF-Resync : AOF 쓰기 작업을 수행할 사용

ü  BIO-LAZY-Free : unlink, FLUSHALL, FLUSHDB 명령어를 실행할 빠른 성능을 보장하기 위해 백그라운드에서 사용

·       Client Process : redis-cli.exe 또는 사용자 애플리케이션에 의해 실행되는 명령어를 실행하기 위해 제공되는 프로세스.

 

 

 

[참고자료]

https://docs.redislabs.com/latest/rs/concepts/

 

 

2019-05-14 / Sungwook Kang / http://sungwookkang.com

 

Redis, Redis Architecture, 레디스 아키텍처, 레디스 스레드, 레디스 프로세스, 레디스 메모리 아키텍처

'NoSql, MemoryDB' 카테고리의 다른 글

Redis Memory LRU(Least Recently Used) 캐시  (0) 2019.06.04
Redis Memory 정보  (0) 2019.05.21
Redis 데이터 타입 – Geo  (0) 2019.05.15
Redis 데이터 타입 – bit  (0) 2019.05.10
Redis 데이터 타입 – Sorted Set  (0) 2019.05.03

 Redis 데이터 타입 – Geo

 

·       Version : Redis 3.2.100 (Windows)

 

Redis Geo 데이터 타입은 위치정보(위도, 경도) 데이터를 효율적으로 저장하고 사용할 있다.  geoadd, geopos, geodist, georadius, geohash 명령어를 사용한다.

 

[geoadd]

데이터를 저장한다.

geoadd key longitude latitude member [longitude latitude member] …

ex) geopos position 127.1058431 37.5164113 “Local A” 127.0980748 37.5301218 “Local 2”

 

 

[geopos]

데이터를 검색한다

geopos key member [member] …

ex) geopos position “Local A” “Local 2”

bitcount key start end

ex) bitcount order:20190509 0 -1

 

 

[geodist]

맴버간의 거리를 반환

geodist key member1 member2 [unit]

ex) geodist position “Local A” “Local 2”

 

 

[georadius]

중심위치로 부터 최대 거리(반지름)으로 지정된 경계 내에 있는 목록을 반환

georadius key longitude latitude radius m|km|ft|mi

ex) georadius position 127 37 50 mi ASC

 

 

 

[참고자료]

https://redis.io/commands

 

2019-05-14 / Sungwook Kang / http://sungwookkang.com

 

Redis, Redis ,geoadd, geopos, geodist, georadius, geohash데이터 타입, 위치정보, 레디스 위치 정보,

'NoSql, MemoryDB' 카테고리의 다른 글

Redis Memory 정보  (0) 2019.05.21
Redis Architecture  (0) 2019.05.18
Redis 데이터 타입 – bit  (0) 2019.05.10
Redis 데이터 타입 – Sorted Set  (0) 2019.05.03
Redis 데이터 타입 - Set  (0) 2019.04.30

 Redis 데이터 타입 – bit

 

·       Version : Redis 3.2.100 (Windows)

 

Redis bit 0 1 표시하며 setbit, getbit, bitcount 명령어를 사용한다.

 

[setbit]

데이터를 저장한다.

Serbit key offset value

ex) setbit order:20190509 1001 1

 

 

[getbit]

데이터를 검색한다.

getbit key offset

ex) getbit order:20190509 1001

 

 

[bitcount]

범위내의 value 카운트를 나타낸다.

bitcount key start end

ex) bitcount order:20190509 0 -1

 

 

 

[참고자료]

https://redis.io/commands

 

2019-05-09 / Sungwook Kang / http://sungwookkang.com

 

Redis, Redis 입력, setbit, getbit, bitcount, redis 데이터 타입, redis sorted set 데이터 타입, 레디스 데이터 타입, 레디스 bit,  레디스 비트값 저장

'NoSql, MemoryDB' 카테고리의 다른 글

Redis Architecture  (0) 2019.05.18
Redis 데이터 타입 – Geo  (0) 2019.05.15
Redis 데이터 타입 – Sorted Set  (0) 2019.05.03
Redis 데이터 타입 - Set  (0) 2019.04.30
Redis 데이터 타입 - List  (0) 2019.04.27

 Redis 데이터 타입 – Sorted Set

 

·       Version : Redis 3.2.100 (Windows)

 

Redis Sorted Set 데이터 타입은 Set 동일한 구조이며 차이점은 데이터가 정렬된 상태로 저장된다는 것이다. 명령어는 zadd, zrange, zcard, zcount, zrank, zrevrank 사용한다.

 

[zadd]

데이터를 저장할때 zadd 명령을 사용한다.

zadd key member member …

ex) zadd order:20190502 1 “{order_id:1, order_name:sungwook, item_name:redis_1, itemprice:1}” 2 “{order_id:2, order_name:sungwook, item_name:redis_2, itemprice:2}”  3 “{order_id:3, order_name:sungwook, item_name:redis_3, itemprice:3}”

 

 

[zrange]

범위에 데이터를 검색한다.

zrange key start stop

ex) zrange order:20190502 0 -1

 

 

 

[zcard]

저장된 value 개수는 scard 명령을 사용한다.

zcard key

ex) zcard order:20190502

 

 

 

[zcount]

범위내의 value 카운트를 나타낸다.

zcount key min max

ex) zcount order:20190502 1 3

 

 

[zrem]

저장되어 있는 value 삭제 한다.

zrem key member member …

ex) zrem order:20190502 1 “{order_id:1, order_name:sungwook, item_name:redis_1, itemprice:1}”

 

 

[zrank]

Data 저장된 value rank 나타낸다.

zrank key member

ex) zrank order:20190502 “{order_id:2, order_name:sungwook, item_name:redis_2, itemprice:2}”

 

[zrevrank]

Data 저장된 value rank 표시하되 리버스된 rank 값을 나타낸다.

zrevrank key member

ex) zrevrank order:20190502 “{order_id:2, order_name:sungwook, item_name:redis_2, itemprice:2}”

 

 

[zscore]

데이터가 저장된 시점의 value 포인터를 나타낸다.

zscore key member

ex) zscore order:20190502 “{order_id:2, order_name:sungwook, item_name:redis_2, itemprice:2}”

 

 

 

[참고자료]

https://redis.io/commands

 

2019-05-02 / Sungwook Kang / http://sungwookkang.com

 

Redis, Redis 입력, zadd, zrange, zcard, zcount, zrank, zrevrank, redis 데이터 타입, redis sorted set 데이터 타입, 레디스 데이터 타입, 레디스 sorted set, 정렬데이터 저장

'NoSql, MemoryDB' 카테고리의 다른 글

Redis 데이터 타입 – Geo  (0) 2019.05.15
Redis 데이터 타입 – bit  (0) 2019.05.10
Redis 데이터 타입 - Set  (0) 2019.04.30
Redis 데이터 타입 - List  (0) 2019.04.27
Redis 데이터 타입 - Hash  (0) 2019.04.26

SQL Server에서 테이블 이름을 변경하지 않고 테이터만 교체하기

 

·       Version : SQL Server

 

SQL Server에서 파티션 테이블을 사용하기 위해서는 SQL Server Enterprise Edition 사용해야한다. Standard Edition에서도 파티션 테이블 처럼 사용하기 위해서는 새로운 테이블을 생성하고 sp_rename 함수를 사용하여 기존테이블과 새로운 테이블의 이름을 변경하는 방식으로 사용하였다.

-- Replace live with staging

BEGIN TRAN

DROP TABLE DataTable;

EXEC sp_rename DataTable_Staging, DataTable;

COMMIT

 

-- Swap live and staging

BEGIN TRAN

EXEC sp_rename DataTable, DataTable_Old;

EXEC sp_rename DataTable_Staging, DataTable;

EXEC sp_rename DataTable_Old, DataTable_Staging;

COMMIT

 

위와 같은 방법을 사용하여 메타 데이터 레벨에서 테이블 이름을 변경하면 스키마가 일치하더라도 이름이 바뀐 테이블이 지정된 이름의 메타 데이터와 연결되지 않는다. 시스템은 캐시된 ObjectID 사용하는데 스왑아웃을 수행하려면 캐시 데이터를 업데이트하는 추가 단계가 필요하다. 스위치 아웃으로 인해 ObjectID 관련 메타정보가 그대로 유지되면 이러한 추가단계가 불필요하다.

 

ALTER TABLE SWITCH TO 명령은 기존 테이블을 유지하면 데이터 세트를 스와핑힌다. 명령을 사용하기 위해서는 스키마 정보가 호환 가능해야한다. 컬럼이름, 컬럼 순서, 조약 조건등 특성이 동일해야한다.

-- Replace live with staging

BEGIN TRAN

TRUNCATE TABLE DataTable;

ALTER TABLE DataTable_Staging SWITCH TO DataTable;

COMMIT

 

-- Swap live and staging

/* Note: An extra table, DataTable_Old, is required to temporarily hold the data being replaced before it is moved into DataTable_Staging. The rename-based approach did not require this extra table. */

BEGIN TRAN

ALTER TABLE DataTable SWITCH TO DataTable_Old;

ALTER TABLE DataTable_Staging SWITCH TO DataTable;

ALTER TABLE DataTable_Old SWITCH TO DataTable_Staging;

COMMIT

 

 

 

 

 

[참고자료]

https://bengribaudo.com/blog/2016/11/15/3521/swapping-data-sets

 

 

2019-05-02 / Sungwook Kang / http://sungwookkang.com

 

SQL Server, partition table, table swap, data set swap, alter table switch to, sp_rename, alter table, 테이블 변경, 테이블 이름 변경, 데이터 변경

 Redis 데이터 타입 - Set

 

·       Version : Redis 3.2.100 (Windows)

 

Redis Set 데이터 타입은 Element 단위로 저장한다. Set 타입의 데이터를 핸들링할 때에는 sadd, smembers, scard, sdiff, sunion 명령어를 사용한다.

 

[sadd]

데이터를 저장할때 sadd 명령을 사용한다.

sadd key member member …

ex) sadd order “order_id:1, order_name:sungwook, item_name:redis, itemprice:0” “order_id:2, order_name:sungwook2, item_name:redis2, itemprice:2”

 

 

 

[smembers]

Set 으로 저장된 데이터 검색은 smembers 명령을 사용한다.

smembers key

ex) Smemebers order

 

 

[scard]

저장된 value 개수는 scard 명령을 사용한다.

scard key

ex) scard order

 

 

[sdiff]

Key 엘레멘트를 비교하여 전자의 key에만 있는 value 출력한다. 아래 예제는 order order_new 비교해서 order에만 있는 value 출력한다.

sadd order_new “order_id:3, order_name:sungwook3, item_name:redis3, itemprice:3”

 

sdiff key key …

sdiff order order_new

 

 

[sdiffstore]

Key 엘레멘트를 비교하여 전자의key에만 있는 value 다른 key 엘레멘트로 저장한다. 아래 예제는  order order_new 비교하여 order 에만 있는 value order_diff 저장한다.

sdiffstore destination key key …

ex) sdiffstore order_diff order order_new

 

 

[sunion]

Key 엘레멘트의 value 합쳐서 출력한다.

sunion key key …

ex) sunion order order_new

 

[sunionstore]

Key 엘레멘트의 value 합쳐서 다른 key 저장한다.

key destination key key …

ex) sunionstore order_union order order_new

 

 

[srem]

저장되어 있는 value 삭제 한다.

srem key member member …

ex) srem order_union “order_id:3, order_name:sungwook3, item_name:redis3, itemprice:3”

 

 

[spop]

저장되어 있는value 에서 random으로 삭제한다.

spop key [count]

spop order_union 1

 

 

[참고자료]

https://redis.io/commands

 

2019-04-29 / Sungwook Kang / http://sungwookkang.com

 

Redis, Redis 입력, sadd, smembers, scard, sdiff, sunion, redis 데이터 타입, redis set 데이터 타입, 레디스 데이터 타입, 레디스 set

 

'NoSql, MemoryDB' 카테고리의 다른 글

Redis 데이터 타입 – bit  (0) 2019.05.10
Redis 데이터 타입 – Sorted Set  (0) 2019.05.03
Redis 데이터 타입 - List  (0) 2019.04.27
Redis 데이터 타입 - Hash  (0) 2019.04.26
Redis 데이터 입력, 수정, 삭제, 조회  (1) 2019.04.25

 Redis 데이터 타입 - List

 

·       Version : Redis 3.2.100 (Windows)

 

Redis List 데이터 타입은 배열(Array) 비슷한 데이터 구조이다. List 타입의 데이터를 핸들링할 때에는 lpush, lrange, rpush, rpop, llen, lindex 명령어를 사용한다.

 

[lpush]

List 타입은 하나의 key 여러 개의 value 저장할 있다.

lpush key value value value …

lpush order:20190426 "<item_id>1</item_id><item_name>redis</item_name><item_price>000</item_price>" "<item_id>2</item_id><item_name>client</item_name><item_price>000</item_price>

 

 

[lrange]

List 형태의 데이터를 검색할때 lrange 명령어를 사용한다. 명령어 사용시 key, start, stop 값을 함께 사용한다. 아래 스크립트는 0 -10개의 리스트값을 검색한다.

lrange key start stop

lrange order:20190426 0 10

 

 

[rpush]

List데이터 타입에서 기존에 저장되어 있는 데이터 마지막에 새로운 value 저장할때 rpush 명령어를 사용한다.

rpush key value value …

rpush order:20190426 "<item_id>3</item_id><item_name>cli</item_name><item_price>000</item_price>"

 

 

[lpushx]

타입에서 기존에 저장되어 있는 데이터 앞에 새로운 value 저장

lpushx key value

lpushx order:20190426 <item_id>4</item_id><item_name>cli</item_name><item_price>000</item_price>"

 

 

[linsert]

Value value 사이에 값을 끼워넣는다. 아래 스크립트는 <item_id>3</item_id>앞에 <item_id>5</item_id> 값을 끼워 넣는다.

linsert key BEFORE|AFTER pivotvalue

linsert order:20190426 before "<item_id>2</item_id><item_name>cli</item_name><item_price>000</item_price>" "<item_id>5</item_id><item_name>cli_5</item_name><item_price>000</item_price>"

[lset]

특정 key 인덱스에 해당하는 value 변경

lset key index value

lset order:20190426 0 "<item_id>5</item_id><item_name>cli_5</item_name><item_price>000</item_price>"

 

 

[rpop]

마지막에 저장된 values값을 제거

rpop key

rpop order:20190426

 

 

[llen]

저장된 values 개수를 출력

llen key

llen order:20190426

 

 

[lindex]

검색하려는 key 특정 인덱스 위치에 저장된 데이터 검색

lindex key

lindex order:20190426 0

 

 

[참고자료]

https://redis.io/commands

 

2019-04-26 / Sungwook Kang / http://sungwookkang.com

 

Redis, Redis 입력, hget, hmset, hmget, redis 데이터 타입, redis list 데이터 타입, 레디스 데이터 타입, 레디스 리스트

 Redis 데이터 타입 - Hash

 

·       Version : Redis 3.2.100 (Windows)

 

Redis 에서 데이터를 저장할때, 하나의 key 여러 개의 Value 저장할때에는 Hash 데이터 타입을 사용할 있다. Hash 데이터 타입은 하나의 key 하나 이상의 value 값을 콜론(:)으로 구분하여 데이터를 저장할 있다. 기본적으로 필드의 갯수는 제한이 없으며, Value 값에 문자열을 사용할 때는 “string” 사용한다.

order_date:20190426, order_name:”sungwook”:”kang”

 

[hmset / hget / hmget]

Hash 타입의 데이터를 입력할때 hmset 명령어를 사용한다. 데이터를 검색할 때에는 hget 명령어를 사용한다.

hmset key field value field value

ex) hmset order:20190426 customer_name “sungwook” item_name “redis server” item_detail “redis 3.2.100 (windows)”

ex) hget order:20190426 customer_name

 

 

Key 정의된 특정 필드의 value 출력할 때에는 hmget 사용한다.

hmget order:20190426 customer_name item_detail

 

[hgetall]

특정 key 값의 모든 필드와 value 검색할 때에는 hgetall 명령을 사용한다.

hgetall 20190426

 

[hkeys / hvals]

Key 대한 모든 field 명을 출력할 때에는 hkeys 명령어를 사용하고, key 대한 모든 value 출력할 때에는 hvals 사용한다.

hkeys order:20190426

hvals order:20190426

 

 

 

[hexists]

Key field값으로 필드의 존재 유무를 확인할 때는 hexists 명령어를 사용한다. 반환되는 값이 1이면 검색한 필드가 존재하며 0이면 존재하지 않는 필드이다.

hexists order:20190426 customer_name

 

 

[hdel]

Key 대한 특정 필드를 삭제 하려면 hdel 명령을 사용한다. Item_name 필드와value 삭제된 것을 확인할 있다다.

hdel order:20190426 item_name

 

 

[참고자료]

https://redis.io/commands

 

2019-04-25 / Sungwook Kang / http://sungwookkang.com

 

Redis, Redis 입력, hget, hmset, hmget, redis 데이터 타입, redis hash 데이터 타입, 레디스 데이터 타입, 레디스 해시

 

'NoSql, MemoryDB' 카테고리의 다른 글

Redis 데이터 타입 - Set  (0) 2019.04.30
Redis 데이터 타입 - List  (0) 2019.04.27
Redis 데이터 입력, 수정, 삭제, 조회  (1) 2019.04.25
Redis - redis-cli를 사용한 Redis Server접속  (0) 2019.04.24
Redis 설치 (Windows)  (1) 2019.04.23

 Redis 데이터 입력, 수정, 삭제, 조회

 

·       Version : Redis 3.2.100 (Windows)

 

Redis 키밸류(Key-Value) 시스템으로 데이터를 입력,수정,삭제,조회를 하기 위해서는 Redis에서 제공하는 명령어를 사용해야 한다. 아래 실습을 통해서 데이터를 핸들링하는 방법에 대해서 알아본다.

 

[set]

데이터를 저장할 때에는 set 명령을 사용한다.

set key value

ex) set 1 “sqlmvp”

 

 

[get]

데이터를 검색할 때에는 get 명령을 사용한다.

get key

ex) get 1

 

 

[rename]

저장된 key 값을 변경할 때에는 rename 명령을 사용한다.

rename key newkey

ex)rename 1 “sqlmvp1”

 

 

[keys]

저장된 모든 키를 검색할때 key 명령을 사용한다.

keys pattern

keys * //모든키 검색

keys s* //s 시작하는 모든 검색

keys *2 //2 끝나는 모든 검색

 

 

[randomkey]

저장된 key 중에 하나의 랜덤한 key 검색할 randomkey 명령을 사용한다.

randomKey

 

 

[exists]

검색 하려는 key 존재하는지 여부를 확인할때 exists 명령어를 사용한다. 반환되는 값이 1이면 존재하는 키값이며, 0이면 존재하지 않는 키값이다.

exists key

ex) exists 1

 

 

[strlen]

검색하려는 key value 길이를 확인할때 strlen 명령을 사용한다.

strlen key

ex)strlen 2

 

 

[flushall]

 현재 저장되어 있는 모든key 삭제 때에는 flushall 명령을 사용한다.

flushall

 

 

[setex]

데이터를 입력할때  일정 시간이 지나 자동으로 삭제하는 명령은 setex 이다. 시간 단위는 (second)이다. 데이터 입력후 ttl key 사용하면 삭제 되기 까지의 시간을 확인할 있다.

setex key second value

ex) setex 1 10 “10 second)

 

 

[mget / mset]

여러개의 key value 한번에 검색/저장할때에는 mget / mset 명령어를 사용한다. mset 명령어 사용시 데이터가 입력 순서대로 저장된다는 보장은 없다.

mset key value key value

ex) mset 1 “data1” 2 “data2” 3 “data3”

 

mget key key key

ex) mget 1 2 3

 

 

[append]

현재 value 값에value 추가할때에는 append 명령어를 사용한다.  추가하려는 value 공백이 없을 경우 기존의 부분에 추가가 되면 공백이 있을경우 기존 값의 부분에 추가 된다.

append key value

ex) append 1 “add data1”

ex) append 1 “ data 2”

 

 

[incr / decr]

특정 key 값의 value 값에 대한 증가 또는 감소 값을 가져올때 incr / decr 명령을 사용한다.

incrby key

ex) incr 1

ex) decr 1

ex) incrby 1 10

ex) decrby 1 50

 

 

[save]

현재 입력되어 있는  key, value 값을 파일러 저장할 때에는 save명령어를 사용한다. Save 명령으로 저장된 데이터는 Redis 폴더의 dump.rdb파일로 생성된다.

save

 

 

[참고자료]

https://redis.io/commands

 

2019-04-24 / Sungwook Kang / http://sungwookkang.com

 

Redis, Redis 입력, get, set, mget, mset, flushall, keys, append, redis 조회, redis 데이터 수정

'NoSql, MemoryDB' 카테고리의 다른 글

Redis 데이터 타입 - List  (0) 2019.04.27
Redis 데이터 타입 - Hash  (0) 2019.04.26
Redis - redis-cli를 사용한 Redis Server접속  (0) 2019.04.24
Redis 설치 (Windows)  (1) 2019.04.23
Cassandra 설치  (0) 2016.10.07

 Redis - redis-cli 사용한 Redis Server접속

 

·       Version : Redis 3.2.100 (Windows)

 

Redis 설치 되어 있으면 설치되어 있는 폴더에서 redis-cli.exe 사용하여 Redis 서버에 접속할 있다. 이때 Redis 인스턴스를 활성화 사용했던 포트 번호를 -p 옵션과 함께 사용한다.

redis-cli.exe -p 6379

 

redis-cli -h 127.0.0.1 -p 6379 -a mypassword

 

Note : 비밀번호에 $ 기호가 있으면 에러가 발생한다.

 

Redis-Shell에서 실행할 있는 명령어 리스트를 조회하려면 help 입력한다.

 

help 명령어와 함께 실행할 명령어를 입력하면 해당 명령어의 자세한 사용법이 표시 된다.

 

 

[참고자료]

https://redis.io/documentation

 

2019-04-23 / Sungwook Kang / http://sungwookkang.com

 

Redis, Redis install for windows,  redis-cli, redis 접속

'NoSql, MemoryDB' 카테고리의 다른 글

Redis 데이터 타입 - List  (0) 2019.04.27
Redis 데이터 타입 - Hash  (0) 2019.04.26
Redis 데이터 입력, 수정, 삭제, 조회  (1) 2019.04.25
Redis 설치 (Windows)  (1) 2019.04.23
Cassandra 설치  (0) 2016.10.07

Redis 설치 (Windows)

 

·       Version : Redis 3.2.100

 

Redis (글을 쓰는 현재)공식적으로 Windows 버전을 지원하지 않는다. 하지만 공식 사이트를 살펴 보면 Microsoft에서 Win-64 port 개발하고 유지한다고 한다.

·       Redis : https://redis.io/topics/introduction

Redis is written in ANSI C and works in most POSIX systems like Linux, *BSD, OS X without external dependencies. Linux and OS X are the two operating systems where Redis is developed and more tested, and we recommend using Linux for deploying. Redis may work in Solaris-derived systems like SmartOS, but the support is best effort. There is no official support for Windows builds, but Microsoft develops and maintains a Win-64 port of Redis.

 

Redis 공식 사이트에서 안내되어있는 링크를 클릭하면 MicrosoftArchive 깃헙으로 연결된다. 아래 깃헙에서 필요한 버전을 다운받아서 설치 한다.

·       Redis for Windows :  https://github.com/MicrosoftArchive/redis/releases

 

Redis 설치가 완료되면 Task Manager – Services 탭에서 Redis 서비스가 실행중인것을 확인할 있다.

 

[참고자료]

·       https://redis.io/topics/introduction

·       https://github.com/MicrosoftArchive/redis/releases

 

2019-04-22 / Sungwook Kang / http://sungwookkang.com

 

Redis, Redis install for windows,  MicrosoftArchive, 레디스, 레디스 설치, NoSQL, Memory DB

'NoSql, MemoryDB' 카테고리의 다른 글

Redis 데이터 타입 - List  (0) 2019.04.27
Redis 데이터 타입 - Hash  (0) 2019.04.26
Redis 데이터 입력, 수정, 삭제, 조회  (1) 2019.04.25
Redis - redis-cli를 사용한 Redis Server접속  (0) 2019.04.24
Cassandra 설치  (0) 2016.10.07

SQL Server master 데이터베이스 정리

 

·       Version : SQL Server

 

SQL Server에서 master 데이터베이스의 역할은 시스템에 대한 모든 정보를 기록한다. 여기에는 로그인 계정, 끝점, 연결된 서버 시스템 구성설정과 같은 인스턴스 차원의 메타 데이터가 포함된다.

·       master database : https://docs.microsoft.com/en-us/sql/relational-databases/databases/master-database?view=sql-server-2017

 

우리는 가끔 의도하지 않게 master 데이터베이스에 개체를 생성하는 경우가 있다. 대부분 개체를 생성할 USE 문을 생략했을 수도 있고 많은 작업창을 띄어 놓고 사용하다가 실수할 수도 있다. 이번 아티클에서는 master 데이터베이스를 정리하는 방법에 대해서 알아본다. master 데이터베이스는 시스템의 설정을 저장하고 있으므로 해당 작업시 주의가 필요 하다.

 

[master에서 삭제하지 않을 목록]

아래 표에 정으되어 있는 오브젝트 유형은 시스템과 관련있기 때문에 삭제 목록에서 제외한다.

ET

External table

IT

Internal table

PC

Assembly (CLR) stored procedure

PG

Plan guide

RF

Replication-filter-procedure

S

System table

SQ

Service queue

TA

Assembly (CLR) DML Trigger

X

Extended procedure

-

CLR User-Defined Data Type (UDDT)

 

사용자는 자신만의 모듈을 생성하여 시스템 객체로 표시할 수도 있다. 경우 시스템 저장프로시저와 구별 있는 확실한 방법이 없기 때문에 주관적으로 식별해야 한다.

 

[master 에서 삭제할 목록]

오브젝트를 삭제하기 위해서는 약간의 순서가 필요하다. 예를 들어 테이블을 삭제하려면 외부키나 뷰를 제거해야하며, 테이블 함수를 사용하는 테이블을 삭제 때까지 파티션 함수를 제거할 없다. 또한 순환 참조가 있을 있으므로 많은 경우 스크립트를 여러번 실행해야 수도 있다.

 

아래 표시된 유형은 객체를 삭제하면 자동으로 삭제되기 때문에 크게 걱정할 필요가 없다.

C

Check constraint

D

Default constraint

PK

Primary key constraint

TR

DML trigger

UQ

Unique constraint

 

나머지는 아래 순서대로 삭제해야한다.

1

F

Foreign key constraint

Need to be dropped before tables, as described below.

2

V

View

Should be dropped before tables, since they can have direct or indirect SCHEMABINDING.

FN

SQL scalar function

IF

SQL inline table-valued function

TF

SQL table-valued-function

3

P

Stored procedure

Need to be dropped before tables, but after views and functions (since procedures can reference views and functions, but can't be referenced by them except in rare cases using OPENQUERY()).

4

U

Table (user-defined)

Dropped after foreign keys and any type of module that can reference them with SCHEMABINDING.

5

TT

Table type

Dropped after tables and modules, but before old-style rules that could be bound to them. Table types need to be dropped before other types.

Alias types

 

6

SO

Sequence object

Dropped after tables/modules because they can't be dropped if any table or module references them.

R

Rule (old-style, stand-alone)

D

Old-style CREATE DEFAULT

Partition functions

 

7

Partition schemes

 

Can't be dropped until after partition functions.

8

SN

Synonym

I drop these toward the end because they can reference many of the items above (though this entity is not really prone to any issues on its own, unless you have external references pointing at them).

9

Schemas

 

I drop these almost last because almost all entities above can belong to a certain schema. For any entities you want to keep but move to a different schema, you'll need to first use ALTER SCHEMA ... TRANSFER.

10

Roles and Users

 

For users you don't want to keep, you'll need to first remove them from user-defined role membership and ownership, as well as ownership of any schemas. 

(For users you do want to keep, you may also want to remove any inappropriate permissions, but I'll deal with that in a separate post.) 

For roles you don't want to keep, you'll need to first remove any members; but you can't remove members who also happen to own roles.

 

[기본 접근]

순환 참조는 여러 개체가 서로를 참조하므로 개체를 삭제하는 올바른 순서를 결정하기가 복잡하다. 그래서 스크립트가 실패하더라도 다시 실행하여 스크립트가 성공할때 까지 반복해서 실행 있는 스크립트로 작성해야 한다. 예를 들어 개의  SCHEMABINDING 뷰를 사용하는 경우 개의 뷰를 모두 삭제해야 테이블이 삭제된다.   순서가 명확하다면 순서대로 하면 되지만 뷰가 여러개 이면서 서로 뷰를 참조하는 경우 순서를 예측하기 어렵기 때문에 삭제 명령을 반복해서 실행한다.

try { drop view 1; go; drop view 2; }

 

 

[삭제 스크립트 (순서대로 실행)]

Foreign keys

-- script to drop Foreign Keys

USE [master];

GO

SET NOCOUNT ON;

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  ALTER TABLE ' + objectname + N'

    DROP CONSTRAINT ' + fkname + N';

END TRY

BEGIN CATCH

  SELECT N''FK ' + fkname + N' failed. Run the script again.'',

    ERROR_MESSAGE();

END CATCH

' FROM

(

  SELECT fkname = QUOTENAME(fk.[name]),

    objectname = QUOTENAME(s.[name]) + N'.' + QUOTENAME(t.[name])

  FROM sys.foreign_keys AS fk

  INNER JOIN sys.objects AS t

  ON fk.parent_object_id = t.[object_id]

  INNER JOIN sys.schemas AS s

  ON t.[schema_id] = s.[schema_id]

) AS src;

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

View and functions

-- script to drop views

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  DROP VIEW ' + objectname + N';

END TRY

BEGIN CATCH

  SELECT N''View ' + objectname + N' failed - run the script again.'',

    ERROR_MESSAGE();

END CATCH

' FROM

(

  SELECT QUOTENAME(s.[name]) + N'.' + QUOTENAME(v.[name])

  FROM sys.views AS v

  INNER JOIN sys.schemas AS s

  ON v.[schema_id] = s.[schema_id]

  WHERE v.is_ms_shipped = 0

) AS src(objectname);

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

-- script to drop functions

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  EXEC sys.sp_executesql N''DROP FUNCTION ' + objectname + N';'';

END TRY

BEGIN CATCH

  SELECT N''Function ' + objectname + N' failed - run the script again.'',

    ERROR_MESSAGE();

END CATCH

' FROM

(

  SELECT QUOTENAME(s.[name]) + N'.' + QUOTENAME(o.[name])

  FROM sys.objects AS o

  INNER JOIN sys.schemas AS s

  ON o.[schema_id] = s.[schema_id]

  WHERE o.is_ms_shipped = 0

  AND o.[type] IN ('FN','IF','TF')

) AS src(objectname);

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

Stored Procedures

-- script to drop procedures

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  EXEC sys.sp_executesql N''DROP PROCEDURE ' + objectname + N';'';

END TRY

BEGIN CATCH

  SELECT N''Procedure ' + objectname + N' failed - run the script again.'',

    ERROR_MESSAGE();

END CATCH

' FROM

(

  SELECT QUOTENAME(s.[name]) + N'.' + QUOTENAME(o.[name])

  FROM sys.objects AS o

  INNER JOIN sys.schemas AS s

  ON o.[schema_id] = s.[schema_id]

  WHERE o.[type] = 'P'

  AND o.is_ms_shipped = 0

) AS src(objectname);

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

Tables

-- script to drop user tables

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  EXEC sys.sp_executesql N''DROP TABLE ' + objectname + N';'';

END TRY

BEGIN CATCH

  SELECT N''Table ' + objectname + N' failed - run the script again.'',

    ERROR_MESSAGE();

END CATCH

' FROM

(

  SELECT QUOTENAME(s.[name]) + N'.' + QUOTENAME(o.[name])

  FROM sys.tables AS o

  INNER JOIN sys.schemas AS s

  ON o.[schema_id] = s.[schema_id]

  WHERE o.is_ms_shipped = 0

) AS src(objectname);

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

Table Types

-- script to drop table types

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  EXEC sys.sp_executesql N''DROP TYPE ' + objectname + N';'';

END TRY

BEGIN CATCH

  SELECT N''Type ' + objectname + N' failed - run the script again.'',

    ERROR_MESSAGE();

END CATCH

' FROM

(

  SELECT QUOTENAME(s.[name]) + N'.' + QUOTENAME(o.[name])

  FROM sys.types AS o

  INNER JOIN sys.schemas AS s

  ON o.[schema_id] = s.[schema_id]

  WHERE o.is_table_type = 1

) AS src(objectname);

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

Alias Types

-- script to drop alias types

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  EXEC sys.sp_executesql N''DROP TYPE ' + objectname + N';'';

END TRY

BEGIN CATCH

  SELECT N''Type ' + objectname + N' failed - run the script again.'',

    ERROR_MESSAGE();

END CATCH

' FROM

(

  SELECT QUOTENAME(s.[name]) + N'.' + QUOTENAME(o.[name])

  FROM sys.types AS o

  INNER JOIN sys.schemas AS s

  ON o.[schema_id] = s.[schema_id]

  WHERE o.user_type_id > 256

  AND o.is_table_type = 0

  AND o.is_assembly_type = 0  -- not a CLR UDT

) AS src(objectname);

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

Sequences

-- script to drop sequences

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  EXEC sys.sp_executesql N''DROP SEQUENCE ' + objectname + N';'';

END TRY

BEGIN CATCH

  SELECT N''Sequence ' + objectname + N' failed - run the script again.'',

    ERROR_MESSAGE();

END CATCH

' FROM

(

  SELECT QUOTENAME(s.[name]) + N'.' + QUOTENAME(o.[name])

  FROM sys.sequences AS o

  INNER JOIN sys.schemas AS s

  ON o.[schema_id] = s.[schema_id]

  WHERE o.is_ms_shipped = 0

) AS src(objectname);

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

Old-style CREATE RULE

-- script to drop old-style Rules

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  EXEC sys.sp_executesql N''DROP RULE ' + objectname + N';'';

END TRY

BEGIN CATCH

  SELECT N''Rule ' + objectname + N' failed - run the script again.'',

    ERROR_MESSAGE();

END CATCH

' FROM

(

  SELECT QUOTENAME(s.[name]) + N'.' + QUOTENAME(o.[name])

  FROM sys.objects AS o

  INNER JOIN sys.schemas AS s

  ON o.[schema_id] = s.[schema_id]

  WHERE o.is_ms_shipped = 0

  AND [type] = 'R'

  AND parent_object_id = 0

) AS src(objectname);

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

Old-style CREATE DEFAULT

-- script to drop old-style Defaults

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  EXEC sys.sp_executesql N''DROP DEFAULT ' + objectname + N';'';

END TRY

BEGIN CATCH

  SELECT N''Default ' + objectname + N' failed - run the script again.'',

    ERROR_MESSAGE();

END CATCH

' FROM

(

  SELECT QUOTENAME(s.[name]) + N'.' + QUOTENAME(o.[name])

  FROM sys.objects AS o

  INNER JOIN sys.schemas AS s

  ON o.[schema_id] = s.[schema_id]

  WHERE o.is_ms_shipped = 0

  AND [type] = 'D'

  AND parent_object_id = 0

) AS src(objectname);

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

Partition functions

-- script to drop partition functions

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  EXEC sys.sp_executesql N''DROP PARITITON FUNCTION ' + objectname + N';'';

END TRY

BEGIN CATCH

  SELECT N''Partition function ' + objectname + N' failed - run the script again.'',

    ERROR_MESSAGE();

END CATCH

' FROM

(

  SELECT QUOTENAME([name])

  FROM sys.partition_functions

) AS src(objectname);

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

Partition schemes

-- script to drop partition schemes

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  EXEC sys.sp_executesql N''DROP PARITITON SCHEME ' + objectname + N';'';

END TRY

BEGIN CATCH

  SELECT N''Partition scheme ' + objectname + N' failed - run the script again.'',

    ERROR_MESSAGE();

END CATCH

' FROM

(

  SELECT QUOTENAME([name])

  FROM sys.partition_schemes

) AS src(objectname);

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

Synonyms

-- script to drop synonyms

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  EXEC sys.sp_executesql N''DROP SYNONYM ' + objectname + N';'';

END TRY

BEGIN CATCH

  SELECT N''Synonym ' + objectname + N' failed - run the script again.'',

    ERROR_MESSAGE();

END CATCH

' FROM

(

  SELECT QUOTENAME(s.[name]) + N'.' + QUOTENAME(o.[name])

  FROM sys.synonyms AS o

  INNER JOIN sys.schemas AS s

  ON o.[schema_id] = s.[schema_id]

) AS src(objectname);

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

Schemas

-- script to drop schemas

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  EXEC sys.sp_executesql N''DROP SCHEMA ' + objectname + N';'';

END TRY

BEGIN CATCH

  SELECT N''Schema ' + objectname + N' failed - run the script again.'',

    ERROR_MESSAGE();

END CATCH

' FROM

(

  SELECT QUOTENAME(s.[name])

  FROM sys.schemas AS s

  WHERE [schema_id] BETWEEN 5 AND 16383

) AS src(objectname);

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

-- script to re-route default schemas

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  ALTER USER ' + QUOTENAME(name) + N' WITH DEFAULT_SCHEMA = dbo;

 END TRY

 BEGIN CATCH

  SELECT N''User ' + p.name + N' failed - run the script again.'',

     ERROR_MESSAGE();

 END CATCH

'

FROM sys.database_principals AS p

WHERE p.default_schema_name IS NOT NULL

AND NOT EXISTS

(

  SELECT 1

  FROM sys.schemas AS s

  WHERE name = p.default_schema_name

);

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

Roles and Users

-- script to change ownership of roles to dbo

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  ALTER AUTHORIZATION ON ROLE::' + QUOTENAME(r.name) + N' TO dbo;

 END TRY

 BEGIN CATCH

   SELECT N''Role ' + r.name + N' failed - run the script again.'',

     ERROR_MESSAGE();

 END CATCH

'

FROM sys.database_principals AS r

INNER JOIN sys.database_principals AS u

ON r.owning_principal_id = u.principal_id

WHERE r.[type] = 'R'

AND u.name NOT IN (N'public', N'dbo', N'guest', N'INFORMATION_SCHEMA', N'sys')

AND u.name NOT LIKE N'##%##' -- hopefully you don't name users/roles this way!

AND r.is_fixed_role = 0;

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

-- script to change ownership of schemas to dbo

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  ALTER AUTHORIZATION ON SCHEMA::' + QUOTENAME(name) + N' TO dbo;

 END TRY

 BEGIN CATCH

  SELECT N''Schema ' + name + N' failed - run the script again.'',

    ERROR_MESSAGE(); END CATCH

'

FROM sys.schemas

WHERE [schema_id] BETWEEN 5 AND 16383

AND principal_id BETWEEN 5 AND 16383;

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

-- script to remove members from roles

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

' + CASE WHEN CONVERT(tinyint,

  PARSENAME(CONVERT(nvarchar(128),

  SERVERPROPERTY(N'ProductVersion')),4)) >= 11 -- 2012+

 THEN

  N'ALTER ROLE ' + QUOTENAME(r.name) + N' DROP MEMBER '

   + QUOTENAME(m.name) + N';'

 ELSE

  N'EXEC [sys].[sp_droprolemember] @rolename = N''' + r.name

    + ''', @membername = N''' + m.name + N''';'

 END + N'

 END TRY

 BEGIN CATCH

   SELECT N''Role ' + r.name + N' failed - run the script again.'',

     ERROR_MESSAGE();

 END CATCH

'

FROM sys.database_role_members AS rm

INNER JOIN sys.database_principals AS r

ON rm.role_principal_id = r.principal_id

AND r.is_fixed_role = 0

INNER JOIN sys.database_principals AS m

ON rm.member_principal_id = m.principal_id;

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

-- script to drop roles

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  DROP ROLE ' + QUOTENAME(r.name) + N';

 END TRY

 BEGIN CATCH

  SELECT N''Role ' + r.name + N' failed - run the script again.'',

     ERROR_MESSAGE();

 END CATCH

'

FROM sys.database_principals AS r

WHERE r.[type] = 'R'

AND r.name <> N'public'

AND r.is_fixed_role = 0;

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

-- script to drop users

USE [master];

GO

DECLARE @sql nvarchar(max) = N'';

 

SELECT @sql += N'BEGIN TRY

  DROP USER ' + QUOTENAME(u.name) + N';

 END TRY

 BEGIN CATCH

  SELECT N''User ' + u.name + N' failed - run the script again.'',

     ERROR_MESSAGE();

 END CATCH

'

FROM sys.database_principals AS u

WHERE u.[type] IN ('U','S')

AND u.name NOT IN (N'public', N'dbo', N'guest', N'INFORMATION_SCHEMA', N'sys')

AND u.name NOT LIKE N'##%##';

 

SELECT @sql;

--EXEC sys.sp_executesql @sql;

 

 

지금까지  master 데이터베이스를 정리하는 작업 순서, 스크립트 생성에 대해서 알아보았다. 객체를 삭제하는 명령은 자동화 있지만 모든것은 완벽히 분석할 수는 없다. (사용자 모듈을 시스템 모듈로 생성한 경우 ) 스크립트를 사용하더라도 생성된 스크립트를 반드시 DBA 검토를 해야한다. master 데이터베이스를 정리하는것은 위험한 작업이므로 반드시 많은 테스트와 검증이 필요하다.

 

[참고자료]

https://www.mssqltips.com/sqlservertip/4530/cleaning-up-the-sql-server-master-database/

 

 

2019-04-18 / Sungwook Kang / http://sungwookkang.com

 

SQL Server, SSMS, mssql, DBA, master database, sys.database_principals, sys.database_role_members, sys.foreign_keys, sys.objects, sys.partition_functions, sys.partition_schemes, sys.procedures, sys.schemas, sys.sequences,

SQL Server 프로토콜과 SQLCMD 사용한 연결

 

·       Version : SQL Server

 

SQL Server 연결하는 것은 이미 많은 문서를 통해서 알려져 있으며 GUI 제공하는 툴들이 많아서 어렵지 않게 느껴질 수가 있다. 하지만 상황에 따라 복잡해 있다. 만약 TCP 포트에서 수신대기를 하지 않는 SQL Server 인스턴스에는 어떻게 연결할까? 호스트 컴퓨터가 서버  DNS 확인할 없는 경우 어떻게  SQL Server 연결할까? 명명된 인스턴스는 무엇일까? 이번 포트스에서 SQLCMD 사용하여 다양한 프로토콜의 의미와 사용법을 알아 본다.

 

SQL Server 관리하는 다양한 툴들이 있다. 특히SSMS(SQL Server Management Studio) Microsoft에서 공식으로 제공하는 SQL Server관리툴이며GUI 제공한다. 그리고 SQLCMD라는 CLI 있다. SQLCMD 경우 명령줄로 이루어져 있다. SQL Server Linux 지원하면서 우리는 GUI 뿐만아니라 환경에도 익숙해져야 하기 때문에 SQLCMD 대해 다루어 본다.

 

SSMS 사용하여 SQL Server 인스턴스에 연결할  특정 프로토콜을 사용하기 위해서 Connection Properties 탭에서 프로토콜을 선택할 있다.

 

대부분 SQL Server 연결할 , 프로토콜을 지정하지 않으면 TCP/IP 사용한다고 생각할 있다. 하지만 프로토콜을 지정하지 않으면 TCP/IP 사용한다는 보장을 없다. SSMS SQLCMD에는 SQL Server 구성관리자의 프로토콜에 따라 순서가 결정된다.  아래 그림은 SQL Server 구성관리자의 프로토콜 구성이다. 구성관리자에는 32bit, 64bit  가지 클라이언트 구성이 있다. SSIS 사용하는 경우 32bit 커넥터를 사용할 있기 때문에 중요하다. 패키자가 64bit 버전에서 실행되고 64bit 설정을 하지 않을 경우 패키지가 실패한다.

 

[SQLCMD 사용한 SQL Server TCP/IP 연결]

TCP/IP 프로토콜을 사용하여 SQL Server 인스턴스에 연결할 , 인스턴스가 기본 포트가 아닌 경우 서버 IP 주소, 또는 호스트 이름과 포트가 필요하다. 아래 스크립트는 TCP/IP 사용하여 연결하는 일반적인 구문이다.

sqlcmd -S tcp:<computer name>,<port number>

 

IP 주소를 입력하면 TCP/IP 프로토콜을 사용할 것이라는 보장을 없다. TCP/IP 보장하기 위해서 tcp:라는 접두어를 사용하여 연결한다. 예를 들어 Windows 인증을 사용하는 SQL Server 기본 인스턴스를 사용하여 SQL-A라는 서버에 TCP/IP 프로토콜을 사용하여 연결하려는 경우 아래 구문을 이용한다.

sqlcmd –S tcp:SQL-A

sqlcmd –S tcp:SQL-A –U sa –P Pa$$w0rd

 

IP 사용할 경우 아래 구문을 이용한다.

sqlcmd –S tcp:10.10.10.10

sqlcmd –S tcp:10.10.10.10 –U sa –P Pa$$w0rd

 

명명된 인스턴스를  사용하는 경우 아래 구문을 이용한다.

sqlcmd –S tcp:SQL-A\TEST

sqlcmd –S tcp:SQL-A\TEST –U sa –P Pa$$w0rd

 

포트를 지정해야 경우 콤마(,) 구분하며 포트를 지정해야 한다. 예를 들어 기본 인스턴스가 1433 포트를 사용하고 TEST 인스턴스가 51613포트를 사용하는 경우 연결 문자열을 아래와 같다.

sqlcmd –S tcp:SQL-A,1433

sqlcmd –S tcp:SQL-A,1433 –U sa –P Pa$$w0rd

 

sqlcmd –S tcp:10.10.10.10,1433

sqlcmd –S tcp:10.10.10.10,1433 –U sa –P Pa$$w0rd

 

sqlcmd –S tcp:SQL-A,51613

sqlcmd –S tcp:SQL-A,51613 –U sa –P Pa$$w0rd

 

sqlcmd –S tcp:10.10.10.10,51613

sqlcmd –S tcp:10.10.10.10,51613 –U sa –P Pa$$w0rd

 

 

[SQLCMD SQL Server 명명된 파이트 연결]

명명된 파이프는 서버와 클라이언트 간의 통신을 위해 명명된, 단방향, 또는 이중 파이프이다. 내부적으로 명명된 파이프의 모든 인스턴스는 동일한 파이프 이름을 갖지만 메시지 기반 통신과 클라이언트 가장을 허용하는 자체 버퍼를 유지한다. 명명된 파이프는 프로세스간 통신(IPC) 의존한다. 명명된 파이프를 사용하여 로컬 인스턴스에 연결하면 해당 파이프가 커널 모드에서 로컬 프로시저 호출(LPC) 실행된다는 점에 유의한다. 일반적으로 프로토콜은 원격 SQL Server 인스턴스에 연결할때 TCP/IP 사용하는것이 바람직하기 때문에 사용되지 않는다. 반면 로컬 인스턴스에 연결할 공유 메모리는 종종 선택되어 사용된다. 아래는 기본 인스턴스의 명명된 파이트 연결구문이다.

\\[COMPUTER NAME OR IP ADDRESS]\pipe\sql\query

 

예를 들어 서버 MYSERVER 기본 인스턴스에 대한 명명된 파이프는 다음과 같다.

\\ MYSERVER \ pipe \ sql \ query

 

명명된 인스턴스의 구문은 다음과 같다.

\\[COMPUTER NAME OR IP ADDRESS]\pipe\MSSQL$[SQL Server Instance Name]\sql\query

 

예를 들어 서버 SQL-A에서  SQL Server 인스턴스 TEST 명명된 파이프를 사용하려는 경우 구문은 아래와 같다.

\\SQL-A\pipe\MSSQL$TEST\sql\query

 

명명된 파이프 프로토콜을 사용하여 SQL Server 인스턴스에 연결하는 것은 TCP/IP 사용하는것과 크게 다르지 않다. 연결문자열에np: 접두어를 사용한다. 아래 구문은 Windows SQL Server 인증을 사용하여 SQL Server 기본 인스턴스와 명명된 인스턴스에 연결한다.

sqlcmd –S np:\\SQL-A\pipe\sql\query

sqlcmd –S np:\\SQL-A\pipe\sql\query –U sa –P Pa$$w0rd

sqlcmd –S np:\\SQL-A\pipe\MSSQL$TEST\sql\query

sqlcmd –S np:\\SQL-A\pipe\MSSQL$TEST\sql\query –U sa –P Pa$$w0rd

 

 

[SQLCMD 사용한  SQL Server 공유 메모리 연결]

프로토콜은 클라이언트 연결이 로컬 서버에서 실행될 때만 사용될 있다. 기본적으로 커널 모드에서 실행되는 로컬 프로시저 호출(LPC)이다. MDAC 2.8 이하를 사용하는 경우 공유 메모리 프로토콜을 사용할 없다. 경우 sqlcmd 자동으로 명명된 파이프로 전환한다. 공유 메모리를 사용하는 접두사는 lpc: 이다.

sqlcmd –S lpc:SQL-A

sqlcmd –S lpc:SQL-A –U sa –P Pa$$w0rd

sqlcmd –S lpc:SQL-A\TEST

sqlcmd –S lpc:SQL-A\TEST –U sa –P Pa$$w0rd

 

 

[참고자료]

https://www.mssqltips.com/sqlservertip/5133/different-ways-to-connect-to-sql-server-using-sqlcmd/

 

 

2019-04-17 / Sungwook Kang / http://sungwookkang.com

 

SQL Server, SSMS, sqlcmd, named pipe, sql server protocol, sql connection, mssql

SQL Server Edition 다운그레이드 확인사항

 

·       Version : SQL Server

 

SQL Server Enterprise Edition 에서 SQL Server Standard Edition으로 다운 그레이드 확인해야 가지 사항에 대해서 알아본다. SQL Server Enterprise Edition SQL Server Standard Edition으로 다운그레이드 일부 구성이 기본값으로 다시 설정된다.

 

[SQL Server 오류 로그 ]

SQL Server 오류 로그 파일의 수가 기본 6개로 재설정된다. 설정을 확인하고 필요한 수로 설정한다. SSMS GUI 사용할 수도 있으며 T-SQL 코드를 사용할 있다.

 

USE [master]

GO

 

EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'NumErrorLogs', REG_DWORD, 99

GO

 

 

[SQL Agent 메일 프로필]

SQL Server Agent 속성의 메일 프로필이 비활성 된다. 메일 프로필 사용 올바른 메일 프로필이 사용되는지 확인 한다. SSMS에서 GUI 사용하거나T-SQL 코드를 사용할 있다.

 

USE [msdb]

GO

 

EXEC msdb.dbo.sp_set_sqlagent_properties @email_save_in_sent_folder=1,

      @databasemail_profile=N'DBServerAlerts_Profile', -- replace with your Agent's profile

      @use_databasemail=1

GO  

 

[토큰 교체 설정]

“Replace tokens for all jobs responses to alert” 옵션을 사용하는 경우 다시 활성화 해야 한다.    그림(SQL Agent 메일 프로필 그림) 처럼 SSMS GUI 사용하거나 T-SQL 코드를 사용할 있다.

USE [msdb]

GO

 

EXEC msdb.dbo.sp_set_sqlagent_properties @alert_replace_runtime_tokens=1

GO

 

[기타 잠재적 문제]

위의 설정은 레지스트리를 통해 구성되는 설정이며 시스템 데이터베이스는 저장되지 않는다.

·       SQL Server 2014 레지스트리 위치는 아래와 같다.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL12.MSSQLSERVER\SQLServerAgent

 

·       SQL Server 2017 레지스트리 위치는 아래와 같다.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL14.MSSQLSERVER\SQLServerAgent.

 

레지스트리 아래 저장되는SQL Server 에이전트는 다음과 같다.

·       AlertFailSafeEmailAddress

·       AlertFailSafeNetSendAddress

·       AlertFailSafeOperator

·       AlertFailSafePagerAddress

·       AlertNotificationMethod

·       DatabaseMailProfile

·       ErrorLogFile

·       ErrorLoggingLevel

·       IdleCPUDuration

·       IdleCPUPercent

·       JobHistoryMaxRows

·       JobHistoryMaxRowsPerJob

·       JobShutdownTimeout

·       MonitorAutoStart

·       RestartSQLServer

·       UseDatabaseMail

 

SQL Server Edition 다운그레이드 사항을 확인하여 시스템 운영에 참고 있도록 한다.

 

 

[참고자료]

https://www.mssqltips.com/sqlservertip/4698/sql-server-edition-postdowngrade-steps/

 

2019-04-11 / Sungwook Kang / http://sungwookkang.com

 

SQL Server, Edition post-down grade, Job Agent, Mail profile, Error log number, Token replacement setting, SQL registry key, MS SQL, SQL Edition

AlwaysOn 구성환경에서 Server Role 체크 Job Agent 실행 중지하기

 

·       Version : SQL Server

 

SQL Server에서 AlwaysOn 구성하였을때, Failover 대비하여 Secondary 서버에서도 Primary서버와 동일하게 계정, Job Agent 등이 구성되어 있어야 한다. 그런데 Secondary 경우 DB 동기화 되고 있는 대기 서버이기 때문에 Job Agent Primary 동일하게 설정하면 Secondary에서 Job 실행 Job Fail 발생한다. 또한 Secondary에서 일부 Job 경우 실행이 되지 말아야 것들이 있다. 아래 스크립트는 AlwaysOn role 확인하여 서버가 Primary 때만 Job Agent 수행되도록 한다. 각각의 Job Agent 번째 단계에 추가하여 Primary Role 아닐때 Job 수행을 중지하도록 한다.

DECLARE @SERVER_ROLE nvarchar(50)

 

SELECT

    @SERVER_ROLE = A.ROLE_DESC

FROM sys.dm_hadr_availability_replica_states AS A

    INNER JOIN sys.availability_groups AS B ON A.GROUP_ID = B.GROUP_ID

WHERE A.IS_LOCAL = 1

 

IF @SERVER_ROLE <> 'PRIMARY'

       EXEC msdb.dbo.sp_stop_job N'Job Name' ;

 

Secondary에서 Job 실행되었을때, Role 확인하는 부분이 있어 Job 중지된것을 확인할 있다.

 

[참고자료]

https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-stop-job-transact-sql?view=sql-server-2017

 

2019-04-10 / Sungwook Kang / http://sungwookkang.com

 

SQL Server, AlwaysOn,  Job Agent, sys.dm_hadr_availability_replica_states, AG Role check

+ Recent posts