Database초보우낙

26. undo tablespace와 temp tablespace의 사용량만 집중적으로 시각화 본문

파이썬

26. undo tablespace와 temp tablespace의 사용량만 집중적으로 시각화

오운학 2024. 4. 22. 13:56

데이터 이행 또는 새로운 데이터 베이스에 테이블 생성 및 인덱스 생성을 하게 되면 반드시 모니터링하면 작업해야하는 테이블 페이스 2개가 있는데 그게 바로 undo tablespace와 temp tablespace입니다.

 

1. undo table space의 사용량을 조회하는 쿼리문을 작성

SELECT
    tablespace_name,
    ROUND(SUM(bytes) / (1024 * 1024), 2) AS "Total_MB",
    ROUND(SUM(maxbytes) / (1024 * 1024), 2) AS "Max_MB",
    ROUND(SUM(bytes - NVL(free_space, 0)) / (1024 * 1024), 2) AS "Used_MB",
    ROUND(NVL(SUM(free_space), 0) / (1024 * 1024), 2) AS "Free_MB",
    ROUND((SUM(bytes - NVL(free_space, 0)) / SUM(bytes)) * 100, 2) AS "Used_Percentage"
FROM (
    SELECT
        tablespace_name,
        bytes,
        maxbytes,
        SUM(bytes) OVER (PARTITION BY tablespace_name) AS free_space
    FROM
        dba_data_files
    WHERE
        tablespace_name IN (SELECT tablespace_name FROM dba_tablespaces WHERE contents = 'UNDO')
)
GROUP BY
    tablespace_name;

undo tablespace와 temp tablespace가 full나는 경우는?

 

undo tablespace가 full이 나는 경우는?

1. 대량의 DML작업을 수행할때

2. 아주 큰 delete 작업을 수행하게 되면

예시) 

insert into target 테이블명
select *
from source테이블명@db링크이름;

 

temporary tablespace가 full이 나는 경우는?

1. 대용량 테이블 인덱스 생성 구문

2. 과도하게 temp를 많이 사용하는 with절

3. 대량의 데이터를 정렬하는 order by 절

 

면접질문 1 : 데이터 이행을 어떤 방법으로 해보셨나요?

데이터 펌프를 이용해서 데이터 이행을 해보았습니다.

 

면접질문2. 데이터 이행시 주의할 사항이 뭔지 대답해주실 수 있으세요?

undo tablespace와 temp tablespace가 full이 나지 않도록 주의하면서 이행해야합니다.

 

undo tablespace와 temp tablespace에서 테이블 스페이스이름과 사용량을 조회하는 쿼리문을 union all로 위아래로 묶어서 하나의 결과로 출력되게 하시오

SELECT 
    tablespace_name,
    ROUND((SUM(bytes - blocks * blocks) / SUM(bytes) * 100), 2) AS "Used_Percentage"
FROM
    dba_temp_files
GROUP BY 
    tablespace_name
UNION ALL
SELECT
    tablespace_name,
    ROUND((SUM(bytes - NVL(free_space, 0)) / SUM(bytes) * 100), 2) AS "Used_Percentage"
FROM (
    SELECT
        tablespace_name,
        bytes,
        SUM(bytes) OVER (PARTITION BY tablespace_name) AS free_space
    FROM
        dba_data_files
    WHERE
        tablespace_name IN (SELECT tablespace_name FROM dba_tablespaces WHERE contents = 'UNDO')
)
GROUP BY
    tablespace_name;

 

위의 결과를 shell script로 작성해서 출력되게 하시오

vi ts2.sh

[orcl:~]$ cat ts2.sh
#!/bin/bash

# Oracle 환경 설정
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1
export PATH=$ORACLE_HOME/bin:$PATH
export ORACLE_SID=orcl

# SQL 쿼리 저장
sql_query="SET PAGESIZE 60;
SET LINESIZE 300;
SELECT 
    tablespace_name,
    ROUND((SUM(bytes - blocks * blocks) / SUM(bytes) * 100), 2) AS \"Used_Percentage\"
FROM
    dba_temp_files
GROUP BY 
    tablespace_name
UNION ALL
SELECT
    tablespace_name,
    ROUND((SUM(bytes - NVL(free_space, 0)) / SUM(bytes) * 100), 2) AS \"Used_Percentage\"
FROM (
    SELECT
        tablespace_name,
        bytes,
        SUM(bytes) OVER (PARTITION BY tablespace_name) AS free_space
    FROM
        dba_data_files
    WHERE
        tablespace_name IN (SELECT tablespace_name FROM dba_tablespaces WHERE contents = 'UNDO')
)
GROUP BY
    tablespace_name;
EXIT;"

# SQLPLUS 실행
echo "$sql_query" | sqlplus -s system/oracle_4U

 

SQL> connect sh/sh
Connected.
SQL>
SQL> create table sales100
  2  as
  3   select * from sales;

Table created.

SQL> insert into sales100
  2   select * from sales100;

918843 rows created.

SQL> /

1837686 rows created.

SQL> /

3675372 rows created.

SQL> commit;

Commit complete.

SQL> delete from sales100;

ts2.sh 를 파이썬에서 불러와서 원형 그래프로 시각화 하기

파이썬에서 ts2.sh 를 호출하는 코드

import paramiko
import matplotlib.pyplot as plt

# 리눅스 서버 정보
hostname = '192.168.56.104'
username = 'oracle'
password = 'oracle'

# bash 스크립트의 경로
script_path = "/home/oracle/ts2.sh"

# SSH 클라이언트 객체 생성
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username=username, password=password)

# bash 스크립트를 실행
stdin, stdout, stderr = ssh.exec_command(f'sh {script_path}')

# 결과 읽기
output = stdout.read().decode('utf-8')
print(output)

 

 

출력된 결과에서 위아래 공백을 잘라낸다.

import paramiko
import matplotlib.pyplot as plt

# 리눅스 서버 정보
hostname = '192.168.56.104'
username = 'oracle'
password = 'oracle'

# bash 스크립트의 경로
script_path = "/home/oracle/ts2.sh"

# SSH 클라이언트 객체 생성
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username=username, password=password)

# bash 스크립트를 실행
stdin, stdout, stderr = ssh.exec_command(f'sh {script_path}')

# 결과 읽기
output = stdout.read().decode('utf-8')
print(output.strip())

뭐가 변한지 모르겠

 

위에 출력된 결과를 리스트 변수에 담으세요

import paramiko
import matplotlib.pyplot as plt

# 리눅스 서버 정보
hostname = '192.168.56.104'
username = 'oracle'
password = 'oracle'

# bash 스크립트의 경로
script_path = "/home/oracle/ts2.sh"

# SSH 클라이언트 객체 생성
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username=username, password=password)

# bash 스크립트를 실행
stdin, stdout, stderr = ssh.exec_command(f'sh {script_path}')

# 결과 읽기
output = stdout.read().decode('utf-8')
a = output.strip().split('\n')
print(a)

위의 결과 리스트에서 컬럼명과 점점이 있는 첫번째 요소와 두번째 요소를 제외하고 출력하시오 !

import paramiko
import matplotlib.pyplot as plt

# 리눅스 서버 정보
hostname = '192.168.56.104'
username = 'oracle'
password = 'oracle'

# bash 스크립트의 경로
script_path = "/home/oracle/ts2.sh"

# SSH 클라이언트 객체 생성
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username=username, password=password)

# bash 스크립트를 실행
stdin, stdout, stderr = ssh.exec_command(f'sh {script_path}')

# 결과 읽기
output = stdout.read().decode('utf-8')
a = output.strip().split('\n')
print(a[2:])

위에 출력되고 있는 결과에서 테이블 스페이스 이름과 사용율 출력되게하시오

import paramiko
import matplotlib.pyplot as plt

# 리눅스 서버 정보
hostname = '192.168.56.104'
username = 'oracle'
password = 'oracle'

# bash 스크립트의 경로
script_path = "/home/oracle/ts2.sh"

# SSH 클라이언트 객체 생성
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username=username, password=password)

# bash 스크립트를 실행
stdin, stdout, stderr = ssh.exec_command(f'sh {script_path}')

# 결과 읽기
output = stdout.read().decode('utf-8')
a = output.strip().split('\n')
a3 = a[2:]

for  i  in  a3:
    print(i)

 

 

위의 결과에서 첫번째 컬럼만 출력하시오

 

import paramiko
import matplotlib.pyplot as plt

# 리눅스 서버 정보
hostname = '192.168.56.104'
username = 'oracle'
password = 'oracle'

# bash 스크립트의 경로
script_path = "/home/oracle/ts2.sh"

# SSH 클라이언트 객체 생성
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username=username, password=password)

# bash 스크립트를 실행
stdin, stdout, stderr = ssh.exec_command(f'sh {script_path}')

# 결과 읽기
output = stdout.read().decode('utf-8')
a = output.strip().split('\n')
a3 = a[2:]

for  i  in  a3:
    print(i.split()[0])

 

이번에는 사용율만 나오게 하세

import paramiko
import matplotlib.pyplot as plt

# 리눅스 서버 정보
hostname = '192.168.56.104'
username = 'oracle'
password = 'oracle'

# bash 스크립트의 경로
script_path = "/home/oracle/ts2.sh"

# SSH 클라이언트 객체 생성
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username=username, password=password)

# bash 스크립트를 실행
stdin, stdout, stderr = ssh.exec_command(f'sh {script_path}')

# 결과 읽기
output = stdout.read().decode('utf-8')
a = output.strip().split('\n')
a3 = a[2:]

for  i  in  a3:
    print(i.split()[1])

위의 데이터를 그래프를 그리기 위한 데이터로 구성해서 리스트로 만드시오 !

import paramiko
import matplotlib.pyplot as plt

# 리눅스 서버 정보
hostname = '192.168.56.104'
username = 'oracle'
password = 'oracle'

# bash 스크립트의 경로
script_path = "/home/oracle/ts2.sh"

# SSH 클라이언트 객체 생성
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username=username, password=password)

# bash 스크립트를 실행
stdin, stdout, stderr = ssh.exec_command(f'sh {script_path}')

# 결과 읽기
output = stdout.read().decode('utf-8')
a = output.strip().split('\\n')
a3 = a[2:]

data = [] 
for  i  in  a3:
    data.append( ( i.split()[0], i.split()[1]) )
print(data)    

여러 그래프를 동시에 출력하기 위한 공간을 생성

 import  matplotlib.pyplot  as plt

fig, axes = plt.subplots(1, len(data), figsize=(10,3) ) 

위의 data 를 enumerate 함수를 이용해서 불러오시오 ! enumerate 함수가 리스트의 인덱스 번호를 가져오는 함수입니다

 import  matplotlib.pyplot  as plt

fig, axes = plt.subplots(1, len(data), figsize=(10,3) ) 

for i , (name, percent) in enumerate(data) :
	axes[i].pie([percent,100- float(percent)])

 

 import  matplotlib.pyplot  as plt

fig, axes = plt.subplots(1, len(data), figsize=(10,3) ) 

for i , (name, percent) in enumerate(data) :
	axes[i].pie([percent,100- float(percent)],labels=['Used', 'Free'], autopct='%1.1f%%' )

import  matplotlib.pyplot  as plt

fig, axes = plt.subplots(1, len(data), figsize=(10,3) ) 

for  i , (name, percent) in enumerate(data):
    axes[i].pie([percent,100- float(percent)], labels=['Used','Free'], autopct='%1.1f%%',
                colors=['#30BF9E','#EF88BE'])
    axes[i].set_title(name)

 

 

위의 코드를 하나의 코드로 모아서 출력합니다.

import paramiko
import matplotlib.pyplot as plt

# 리눅스 서버 정보
hostname = '192.168.56.104'
username = 'oracle'
password = 'oracle'

# bash 스크립트의 경로
script_path = "/home/oracle/ts2.sh"

# SSH 클라이언트 객체 생성
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username=username, password=password)

# bash 스크립트를 실행
stdin, stdout, stderr = ssh.exec_command(f'sh {script_path}')

# 결과 읽기
output = stdout.read().decode('utf-8')
a = output.strip().split('\\n')
a3 = a[2:]

data = [] 
for  i  in  a3:
    data.append( ( i.split()[0], i.split()[1]) )
    

import  matplotlib.pyplot  as plt

fig, axes = plt.subplots(1, len(data), figsize=(10,3) ) 

for  i , (name, percent) in enumerate(data):
    axes[i].pie([percent,100- float(percent)], labels=['Used','Free'], autopct='%1.1f%%',
                colors=['#30BF9E','#EF88BE'])
    axes[i].set_title(name)

 

 

 

while True:
    print(""" ===  dba 작업을 편하게 수행하기 위한 스크립트 총모음 ====

                0.   프로그램을 종료하려면 0번을 누르세요.
                1.   alert log file 을 분석해서 로그 스위치 주기 확인
                2.   alert log file에서 가장 많이 나오는 에러번호와 그 건수 확인
                3.   fast recovery area영역의 사용율을 확인하려면 3번을 누르세요
                4.   tablespace의 사용량을 확인하려면 4번을 누르세요
        """)

    num = int(input('원하는 번호를 입력하세요 ~'))
    if num == 0:
        break
        
    elif num == 1:
        import paramiko   # SSH 접속을 위한 라이브러리를 임폴트 합니다. 

        # 리눅스 서버 정보
        hostname = '192.168.56.104'    # 서버의 접속 가능한 IP 주소
        username = 'oracle'            # 접속할 유져명
        password = 'oracle'            # 접속할 유져의 패스워드
        
        # bash 스크립트의 경로
        script_path = "/home/oracle/a.sh"  # 실행할 bash 스크립트의 경로입니다.
        
        # SSH 클라이언트 객체 생성
        ssh = paramiko.SSHClient()  # ssh 클라이언트 객체를 생성합니다.
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
        # host key policy 를 자동으로  추가하도록 설정합니다.
        
        # 리눅스 서버에 접속
        ssh.connect(hostname, username=username, password=password)
        
        # bash 스크립트를 실행하고 그 결과를 저장합니다.
        stdin, stdout, stderr = ssh.exec_command(f'sh {script_path}')
        
        # 결과를 바이트에서 문자열로 디코드
        output = stdout.read().decode('utf-8')
        
        # 줄바꿈 문자를 기준으로 문자열을 분할하여 리스트로 변환
        output_list = output.split('\n')
        
        # 마지막 요소가 빈 문자열일 경우 제거
        if output_list[-1] == '':
            output_list.pop()
        
        import  pandas  as  pd
        
        df = pd.DataFrame(output_list, columns=['col1'])
        df['col1'] = pd.to_datetime(df['col1'])  # 문자형을 날짜형으로 변환합니다.
        df['time_diff'] = df['col1'].diff()  # time_diff 라는 컬럼을 추가하는데 
        print(df)
        break
    elif num == 2:
        file = open('C:\\test\\alert_orcl.log', 'r')
        text = file.read()
    
        text2 = text.split() # 문자열을 어절별로 분리해서 text2 리스트를 구성
        k = []
        for i in text2:  # 리스트의 요소를 하나씩 불러오는데
            if 'ora-' in i.lower():  # 요소를 소문자로 변환하고 그 요소가 ora- 를 포함하면
                k.append(i)   # k 리스트의 요소로 i 에 들어있는 값을 추가합니다.
    
        import pandas as pd
    
        df = pd.DataFrame(k, columns=['col1'])  # k 리스트를 가지고 df 라는 판다스 데이터
        df                                      # 프레임을 생성하는데 컬럼을 col1 으로 지정
    
        from pandasql import sqldf
        pysqldf = lambda q: sqldf(q, globals())
        q = """select col1, count(*)
                from df
                group by col1
                order by 2 desc;"""
    
        print(pysqldf(q))
        break
    elif num == 3:
        import paramiko

        # 리눅스 서버 정보
        hostname = '192.168.56.104'
        username = 'oracle'
        password = 'oracle'

        # bash 스크립트의 경로
        script_path = "/home/oracle/fra.sh"

        # SSH 클라이언트 객체 생성
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(hostname, username=username, password=password)

        # bash 스크립트를 실행
        stdin, stdout, stderr = ssh.exec_command(f'sh {script_path}')


        # 결과 읽기
        output = stdout.read().decode('utf-8')

        # 에러 메시지 읽기
        error = stderr.read().decode('utf-8')


        # 줄바꿈 문자를 기준으로 문자열을 분할하여 리스트로 변환
        output_list = output.split('\n')
        if output_list[-1] == '':
            output_list.pop()

        # 결과 리스트 출력
        print(output_list[0])

        ## 원형 그래프 그리는 코드 

        import matplotlib.pyplot as plt  # 그래프 그리는 전문 모듈

        # 사용된 FRA 비율
        used_percentage = float(output_list[0])

        # 원형 그래프 데이터
        sizes = [used_percentage, 100 - used_percentage]  # 사용된 부분과 남은 부분
        labels = ['Used', 'Free']
        colors = ['#ff9999','#66b3ff']  # 색상 선택

        # 원형 그래프 생성 (여기서 그래프 크기를 조정합니다)
        plt.figure(figsize=(4, 4))  # 그래프 크기를 작게 설정 (이전에는 7x7이었음)
        plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90)
        plt.axis('equal')  # 원형 유지를 위해 같은 축 스케일 사용

        # 원형 그래프 표시
        plt.title('Oracle Fast recovery area usage')
        plt.show()
        break
    elif num == 4:
        import paramiko
        import matplotlib.pyplot as plt

        # 리눅스 서버 정보
        hostname = '192.168.56.104'
        username = 'oracle'
        password = 'oracle'

        # bash 스크립트의 경로
        script_path = "/home/oracle/ts2.sh"

        # SSH 클라이언트 객체 생성
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(hostname, username=username, password=password)

        # bash 스크립트를 실행
        stdin, stdout, stderr = ssh.exec_command(f'sh {script_path}')

        # 결과 읽기
        output = stdout.read().decode('utf-8')
        a = output.strip().split('\n')
        a3 = a[2:]

        data = [] 
        for  i  in  a3:
            data.append( ( i.split()[0], i.split()[1]) )


        import  matplotlib.pyplot  as plt

        fig, axes = plt.subplots(1, len(data), figsize=(10,3) ) 

        for  i , (name, percent) in enumerate(data):
            axes[i].pie([percent,100- float(percent)], labels=['Used','Free'], autopct='%1.1f%%',
                        colors=['#2EEFD9','#EF88BE'])
            axes[i].set_title(name)