MSSQL 을 사용하다 유지관리계획의 작업을 삭제를 하려고 하면 아래와 같은 에러 메시지가 나온다.

 

DELETE 문이 REFERENCE 제약 조건 “FK_subplan_job_id”과(와) 충돌했습니다. 데이터베이스 “msdb”, 테이블 “dbo.sysmaintplan_subplans”, column ‘job_id’에서 충돌이 발생했습니다.
문이 종료되었습니다. (Microsoft SQL Server, 오류: 547)

도움말을 보려면 다음을 클릭하십시오: http://go.microsoft.com/fwlink?ProdName=Microsoft%20SQL%20Server&ProdVer=13.00.5026&EvtSrc=MSSQLServer&EvtID=547&LinkId=20476

 

 

아래 이미지와 같이 작업에서 DAY_BACKUP 작업관리를 삭제하려면 에레메시지가 발생된다.
원인은 sysmainplan_plans 테이블의 ID값과 해당 작업의 로그가 쌓이는 sysmaintplan_log의 ID값이 서로 다르기 때문에 발생한다.
그럼 이제 이럴경우 삭제하는 방법을 간단하게 알아보자.

 

 

 

 

1.먼저 삭제할 작업의  목록을 선택 후 작업 스크립팅 -> DROP -> 새쿼리 편집기 창을 클릭한다.

 

 

2. 쿼리 실행창이 나타나며 job_ip가 확인된다 이 job_id를 복사를 한다.


3. 새쿼리 창을 뛰어서  아래와 같이 명령어를 입력한다

1

2

use master

select * from msdb.dbo.sysmaintplan_subplans where job_id='19c04eaf-2ec4-47fe-816c-0ba0d23874d88'

 

명령어를 입력하면  plan_id값이 출력된다 이제 이 값을 복사하자

 


4. 위에서 확인된 plan_id값을 복사하였으며 아래와 같이 delete  쿼리문으로 삭제를 해준다

1

2

3

4

use master

delete from msdb.dbo.sysmaintplan_log where plan_id='8759DB1-A425-47F8-94C3-0B0DCF177277'

 

delete from msdb.dbo.sysmaintplan_subplans where plan_id='8759DB1-A425-47F8-94C3-0B0DCF177277'

 

 

5.이제 삭제에서 에러가 났던 부분을 삭제를 해보자 정상적으로 삭제가 된 것을 확인 할 수 있다.

 

 


모두 정상적으로 삭제가 완료된 상태

 

운영환경에서 데이터가 증가하면서 혹은 통계업데이트에 의해 실행계획이 변경되어 쿼리가 갑자기 이전보다 확 느려질 수 있다.

 

아래와 같은 방법으로 실행계획을 확인할 수 있다.

 

1) 문제의 쿼리 찾기

--spid 찾기

select hostname, hostprocess, spid 
from master..sysprocesses
where  hostname = '호스트네임'

SELECT client_net_address, session_id
FROM sys.dm_exec_connections
WHERE client_net_address = 'IP'

 

--실행중인 쿼리 확인
SELECT 
  sqltext.TEXT,
  req.status,
  req.command,
  req.cpu_time,
  req.total_elapsed_time,
  req.blocking_session_id,
  req.percent_complete,
  req.plan_handle -- 실행계획 확인할 때 사용
FROM sys.dm_exec_requests req
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS sqltext
where req.session_id = SPID

 

2) 실행계획 확인하기

SELECT *  FROM sys.dm_exec_query_plan (req.plan_handle); 

 

3) 예상 실행계획 삭제

DBCC FREEPROCCACHE (0x06000700A9F6B63640212E7B280000000000000000000000)

 

4) 캐시에 실행계획이 삭제되었는지 확인

SELECT TOP 10 UseCounts, Cacheobjtype, Objtype, TEXT, query_plan
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
CROSS APPLY sys.dm_exec_query_plan(plan_handle)

 

5) 문제의 쿼리 재수행

 

위 방법으로도 해결이 되지 않는다면 실행계획을 분석하여 쿼리 실행에 부하요소를 주는 근본적인 원인을 찾아야 한다.

SELECT
session_id,
start_time,
status,
command,
percent_complete,
estimated_completion_time,
estimated_completion_time /60/1000 as estimate_completion_minutes,
--(select convert(varchar(5),getdate(),8)),
DATEADD(n,(estimated_completion_time /60/1000),GETDATE()) as estimated_completion_time
FROM    sys.dm_exec_requests where command = 'BACKUP DATABASE' OR command = 'RESTORE DATABASE'

-- Backup Script

DECLARE @name VARCHAR(50) -- database name   

DECLARE @path VARCHAR(256) -- path for backup files   

DECLARE @fileName VARCHAR(256) -- filename for backup   

DECLARE @fileDate VARCHAR(20) -- used for file name  

 

SET @path = 'C:\Backup\'

 

SELECT @fileDate = CONVERT(VARCHAR(20),GETDATE(),112) + '_' + REPLACE(CONVERT(VARCHAR(20),GETDATE(),108),':','')

 

DECLARE db_cursor CURSOR FOR

      SELECT name

      FROM master.dbo.sysdatabases  

      WHERE name NOT IN ('master','model','msdb','tempdb')  

      AND DATABASEPROPERTYEX(name, 'Recovery') IN ('FULL','BULK_LOGGED') 

 

OPEN db_cursor    

FETCH NEXT FROM db_cursor INTO @name    

 

WHILE @@FETCH_STATUS = 0    

BEGIN    

      SET @fileName = @path + @name + '_' + @fileDate + '.TRN'   

      BACKUP LOG @name TO DISK = @fileName   

 

      FETCH NEXT FROM db_cursor INTO @name    

END    

 

CLOSE db_cursor    

DEALLOCATE db_cursor

monitorsql.z01
10.00MB
monitorsql.z02
10.00MB
monitorsql.zip
0.63MB
https://www.devart.com/dbforge/sql/monitor/

1. event scheduler의 상태 확인
SHOW VARIABLES LIKE 'event%';



2. event scheduler ON/OFF
SET GLOBAL event_scheduler = ON ;
SET GLOBAL event_scheduler = OFF ;


3. event scheduler 확인 Query
SELECT * FROM information_schema.events;



4. event scheduler 생성하기


(MONTH : 월 / HOUR : 시간 / DAY : 일)등으로 Scheduler 설정이 가능합니다.
수행할 작업은 DO 아래행에 작성하시면 되며, 저는 Procedure로 작성해 봤습니다.
일반 쿼리문을 사용해도 됩니다. (select * from ....)

5. event scheduler 수정하기



6. event scheduler 삭제하기

 

'Database > MySql' 카테고리의 다른 글

PostgreSQL(13.1) FDW(2.3) oci.h: No such file or directory  (0) 2021.02.01
MySQL 데이터 경로 변경하는 방법  (0) 2020.12.29
MySql RPM  (0) 2020.08.28

Mysql datadir 경로 확인 및 Mysql service 중지

mysql 접속 하여 아래와 같은 명령어로 datadir 경로를 확인 하고 서비스를 중단 한다.

mysql> select @@datadir;

+-----------------+

| @@datadir       |

+-----------------+

| /var/lib/mysql/ |

+-----------------+

1 row in set (0.00 sec)

\q

 

 

systemctl stop mysql

 

새로운 Mysql datadir 생성 및 경로 복사 하기

아래와 같은 명령어로 새로운 Mysql datadir 생성 후 Mysql datadir 경로 복사 한다. 권한 또한 부여 한다.

mkdir /data/

rsync -av /var/lib/mysql /data/

chown -R mysql:mysql /data/mysql

 

my.cnf 파일 수정

/etc/my.cnf을 아래와 같이 수정 한다.

vi /etc/my.cnf

 

 

[mysqld]

datadir=/data/mysql

socket=/data/mysql/mysql.sock

 

 

[client]

socket=/data/mysql/mysql.sock

 

 

#symbolic-links=0

#sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

 

SELinux 보안 context에 추가 및 서비스 시작

아래와 같은 명령어로 SELinux 보안 context에 적용을 시키고 서비스를 시작한다.

semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?"

restorecon -R /data/mysql

systemctl start mysql

 

변경된 datadir 확인 하기

mysql접속 하여 datadir 경로가 바뀌었음을 확인 할 수 있다.

mysql> select @@datadir;

+--------------+

| @@datadir    |

+--------------+

| /data/mysql/ |

+--------------+

1 row in set (0.00 sec)

database가 생성 될 때마다 /data/mysql/ 아래로 database가 생성이 된다.

'Database > MySql' 카테고리의 다른 글

PostgreSQL(13.1) FDW(2.3) oci.h: No such file or directory  (0) 2021.02.01
이벤트 스케줄러 사용하기(event scheduler)  (0) 2021.01.06
MySql RPM  (0) 2020.08.28

 

SELECT  s.name + '.' + t.Name AS [Table Name], part.rows AS [Total Rows In Table - Modified],

 CAST((SUMDISTINCT au.Total_pages) * 8 ) / 1024.000 / 1024.000 AS NUMERIC(183)) 

 AS [Table's Total Space In GB]

FROM 

 SYS.Tables t INNER JOIN sys.schemas s ON t.schema_id = s.schema_id

 INNER JOIN SYS.Indexes idx ON t.Object_id = idx.Object_id

 INNER JOIN SYS.Partitions part ON idx.Object_id = part.Object_id 

                    AND idx.Index_id = part.Index_id

 INNER JOIN SYS.Allocation_units au ON part.Partition_id = au.Container_id

 INNER JOIN SYS.Filegroups fGrp ON idx.Data_space_id = fGrp.Data_space_id

 INNER JOIN SYS.Database_files Df ON Df.Data_space_id = fGrp.Data_space_id

WHERE t.Is_ms_shipped = 0 AND idx.Object_id > 255 

GROUP BY t.Name, s.name, part.rows

ORDER BY [Table's Total Space In GB] DESC

'Database > Query' 카테고리의 다른 글

INDEX 상세 정보 조회  (0) 2020.11.02
프로시저 파리미터  (0) 2020.10.20
DELETE 복원 프로시저  (0) 2020.10.20
EXEC와 동적(adhoc) 쿼리  (0) 2020.10.05
Find and Kill all the Blocked Process/Query  (0) 2020.09.22

declare @SchemaName sysname=NULL

, @TableName sysname=NULL

, @IndexName sysname=NULL

, @dataspace sysname=NULL

 

set @SchemaName = 'Sales'

set @TableName = 'SalesOrderDetail'

--set @IndexName = 'AK_SalesOrderDetail_rowguid'

 

 

declare @_SchemaName varchar(100)

declare @_TableName varchar(256)

declare @_IndexName varchar(256)

declare @ColumnName varchar(256)

declare @is_unique varchar(100)

declare @IndexTypeDesc varchar(100)

declare @FileGroupName varchar(100)

declare @is_disabled varchar(100)

declare @IndexColumnId int

declare @IsDescendingKey int

declare @IsIncludedColumn int

 

 

-- getting the index sizes

SELECT schema_name(t.schema_id) [SchemaName],

OBJECT_NAME(ix.OBJECT_ID) AS TableName,

ix.name AS IndexName,

CAST( 8 * SUM(a.used_pages)/1024.0 AS DECIMAL(20,1))AS 'Indexsize(MB)'

INTO #IndexSizeTable

from sys.tables t

inner join sys.indexes ix on t.object_id=ix.object_id

inner join sys.partitions AS p ON p.OBJECT_ID = ix.OBJECT_ID AND p.index_id = ix.index_id

inner join sys.allocation_units AS a ON a.container_id = p.partition_id

WHERE ix.type>0 and t.is_ms_shipped=0

and schema_name(t.schema_id)= isnull(@SchemaName,schema_name(t.schema_id)) and t.name=isnull(@TableName,t.name) AND ix.name=isnull(@IndexName, ix.name)

GROUP BY schema_name(t.schema_id), ix.OBJECT_ID,ix.name

ORDER BY OBJECT_NAME(ix.OBJECT_ID),ix.name

 

--getting important properties of indexes

select schema_name(t.schema_id) [SchemaName], t.name TableName, ix.name IndexName,

cast( '' as varchar(max)) AS IndexKeys, casT('' as varchar(max)) AS IncludedColumns,

ix.is_unique

, ix.type_desc, ix.fill_factor as [Fill_Factor]

, ix.is_disabled , da.name as data_space,

ix.is_padded,

ix.allow_page_locks,

ix.allow_row_locks,

INDEXPROPERTY(t.object_id, ix.name, 'IsAutoStatistics') IsAutoStatistics ,

ix.ignore_dup_key

INTO #helpindex

from sys.tables t

inner join sys.indexes ix on t.object_id=ix.object_id

inner join sys.data_spaces da on da.data_space_id= ix.data_space_id

where ix.type>0 and t.is_ms_shipped=0

and schema_name(t.schema_id)= isnull(@SchemaName,schema_name(t.schema_id)) and t.name=isnull(@TableName,t.name) AND ix.name=isnull(@IndexName, ix.name)

and da.name=isnull(@dataspace,da.name)

order by schema_name(t.schema_id), t.name, ix.name

 

---getting the index keys and included columns

declare CursorIndex cursor for

select schema_name(t.schema_id) [schema_name], t.name, ix.name

from sys.tables t

inner join sys.indexes ix on t.object_id=ix.object_id

where ix.type>0 and t.is_ms_shipped=0

and schema_name(t.schema_id)= isnull(@SchemaName,schema_name(t.schema_id)) and t.name=isnull(@TableName,t.name) AND ix.name=isnull(@IndexName, ix.name)

order by schema_name(t.schema_id), t.name, ix.name

open CursorIndex

fetch next from CursorIndex into @_SchemaName, @_TableName, @_IndexName

while (@@fetch_status=0)

begin

declare @IndexColumns varchar(4000)

declare @IncludedColumns varchar(4000)

set @IndexColumns=''

set @IncludedColumns=''

declare CursorIndexColumn cursor for

select col.name, ixc.is_descending_key, ixc.is_included_column

from sys.tables tb

inner join sys.indexes ix on tb.object_id=ix.object_id

inner join sys.index_columns ixc on ix.object_id=ixc.object_id and ix.index_id= ixc.index_id

inner join sys.columns col on ixc.object_id =col.object_id and ixc.column_id=col.column_id

where ix.type>0 and tb.is_ms_shipped=0

and schema_name(tb.schema_id)=@_SchemaName and tb.name=@_TableName and ix.name=@_IndexName

order by ixc.index_column_id

 

open CursorIndexColumn

fetch next from CursorIndexColumn into @ColumnName, @IsDescendingKey, @IsIncludedColumn

while (@@fetch_status=0)

begin

if @IsIncludedColumn=0

set @IndexColumns=@IndexColumns + @ColumnName +', '

else

set @IncludedColumns=@IncludedColumns + @ColumnName +', '

 

fetch next from CursorIndexColumn into @ColumnName, @IsDescendingKey, @IsIncludedColumn

end

close CursorIndexColumn

deallocate CursorIndexColumn

 

set @IndexColumns = substring(@IndexColumns, 1, len(@IndexColumns)-1)

set @IncludedColumns = case when len(@IncludedColumns) >0 then substring(@IncludedColumns, 1, len(@IncludedColumns)-1) else '' end

 

UPDATE #helpindex

SET IndexKeys = @IndexColumns, IncludedColumns=@IncludedColumns

WHERE [SchemaName]=@_SchemaName and TableName=@_TableName and IndexName=@_IndexName

 

fetch next from CursorIndex into @_SchemaName, @_TableName, @_IndexName

 

end

close CursorIndex

deallocate CursorIndex

 

--showing the results

SELECT hi.SchemaName, hi.TableName, hi.IndexName, hi.IndexKeys, hi.IncludedColumns, ixs.[Indexsize(MB)],

hi.is_unique, hi.type_desc,hi.data_space, hi.Fill_Factor, hi.IsAutoStatistics,

hi.is_disabled, hi.is_padded, hi.allow_page_locks, hi.allow_row_locks,hi.ignore_dup_key

FROM #helpindex hi

INNER JOIN #IndexSizeTable ixs ON hi.SchemaName=ixs.SchemaName and hi.TableName=ixs.TableName and hi.IndexName=ixs.IndexName

order by hi.SchemaName, hi.TableName, hi.IndexKeys, hi.IncludedColumns

 

drop table #helpindex

drop table #IndexSizeTable

'Database > Query' 카테고리의 다른 글

테이블 사이즈  (0) 2020.11.13
프로시저 파리미터  (0) 2020.10.20
DELETE 복원 프로시저  (0) 2020.10.20
EXEC와 동적(adhoc) 쿼리  (0) 2020.10.05
Find and Kill all the Blocked Process/Query  (0) 2020.09.22

sp_helpdb tempdb

go

 

 

ALTER DATABASE tempdb ADD FILE ( NAME = N'tempdev2',

FILENAME = N'E:\Program Files\Microsoft SQL Server\MSSQL12.GHOST\MSSQL\DATA\tempdev2.ndf' , SIZE =2MB , FILEGROWTH = 2MB)

ALTER DATABASE tempdb ADD FILE ( NAME = N'tempdev3',

FILENAME = N'E:\Program Files\Microsoft SQL Server\MSSQL12.GHOST\MSSQL\DATA\tempdev3.ndf' , SIZE =3MB , FILEGROWTH = 3MB)

ALTER DATABASE tempdb ADD FILE ( NAME = N'tempdev4',

FILENAME = N'E:\Program Files\Microsoft SQL Server\MSSQL12.GHOST\MSSQL\DATA\tempdev4.ndf' , SIZE =4MB , FILEGROWTH = 4MB)

ALTER DATABASE tempdb ADD FILE ( NAME = N'tempdev5',

FILENAME = N'E:\Program Files\Microsoft SQL Server\MSSQL12.GHOST\MSSQL\DATA\tempdev5.ndf' , SIZE =5MB , FILEGROWTH = 5MB)

ALTER DATABASE tempdb ADD FILE ( NAME = N'tempdev6',

FILENAME = N'E:\Program Files\Microsoft SQL Server\MSSQL12.GHOST\MSSQL\DATA\tempdev6.ndf' , SIZE =6MB , FILEGROWTH = 6MB)

ALTER DATABASE tempdb ADD FILE ( NAME = N'tempdev7',

FILENAME = N'E:\Program Files\Microsoft SQL Server\MSSQL12.GHOST\MSSQL\DATA\tempdev7.ndf' , SIZE =7MB , FILEGROWTH = 7MB)

ALTER DATABASE tempdb ADD FILE ( NAME = N'tempdev8',

FILENAME = N'E:\Program Files\Microsoft SQL Server\MSSQL12.GHOST\MSSQL\DATA\tempdev8.ndf' , SIZE =8MB , FILEGROWTH = 8MB)

ALTER DATABASE tempdb ADD FILE ( NAME = N'tempdev9',

FILENAME = N'E:\Program Files\Microsoft SQL Server\MSSQL12.GHOST\MSSQL\DATA\tempdev9.ndf' , SIZE =9MB , FILEGROWTH = 9MB)

 

sp_helpdb tempdb

go

 

 

 

[작업내역]

1. tempdev9 파일을 제거하기

 

-- 데이터파일을 초기화 단계.

USE tempdb

GO

DBCC SHRINKFILE (tempdev9, EMPTYFILE);

GO

 

/*

DbId    FileId    CurrentSize    MinimumSize    UsedPages    EstimatedPages

2        10        1152        1152        0            0

*/

-- 데이터파일 제거 단계.

 

ALTER DATABASE tempdb

REMOVE FILE tempdev9; --to delete "tempdev12" data file

GO

 

-- 제거된 결과보기

sp_helpdb tempdb

 

2. 각기 다른 파일 사이즈 통일하기.

 

-- 8MB에서 5MB 로 줄이기

USE [tempdb]

GO

    DBCC SHRINKFILE (N'tempdev' , 5)

    GO

 

 

    DBCC SHRINKFILE (N'tempdev6' , 5)

    DBCC SHRINKFILE (N'tempdev7' , 5)

    DBCC SHRINKFILE (N'tempdev8' , 5)

 

 

-- 작은 파일은 늘려주기

USE [master]

GO

    ALTER DATABASE [tempdb] MODIFY FILE ( NAME = N'tempdev2', SIZE = 5MB, filegrowth=5MB )

    ALTER DATABASE [tempdb] MODIFY FILE ( NAME = N'tempdev3', SIZE = 5MB, filegrowth=5MB )

    ALTER DATABASE [tempdb] MODIFY FILE ( NAME = N'tempdev4', SIZE = 5MB, filegrowth=5MB )

 

    ALTER DATABASE [tempdb] MODIFY FILE ( NAME = N'tempdev6', filegrowth=5MB )

    ALTER DATABASE [tempdb] MODIFY FILE ( NAME = N'tempdev7', filegrowth=5MB )

    ALTER DATABASE [tempdb] MODIFY FILE ( NAME = N'tempdev8', filegrowth=5MB )

 

-- 최종 결과 확인

    select DB_NAME(mf.database_id) database_name

    , mf.name logical_name, mf.file_id

    , CONVERT (DECIMAL (20,2)

    , (CONVERT(DECIMAL, size)/128)) as [file_size_MB]

    , CASE mf.is_percent_growth

    WHEN 1 THEN 'Yes'

    ELSE 'No'

    END AS [is_percent_growth]

    , CASE mf.is_percent_growth

    WHEN 1 THEN CONVERT(VARCHAR, mf.growth) + '%'

    WHEN 0 THEN CONVERT(VARCHAR, mf.growth/128) + ' MB'

    END AS [growth_in_increment_of]

    , CASE mf.is_percent_growth

    WHEN 1 THEN CONVERT(DECIMAL(20,2)

    ,(((CONVERT(DECIMAL, size)*growth)/100)*8)/1024)

    WHEN 0 THEN CONVERT(DECIMAL(20,2)

    , (CONVERT(DECIMAL, growth)/128))

    END AS [next_auto_growth_size_MB]

    , physical_name from sys.master_files mf

    where database_id =2 and type_desc= 'rows'

 

 

 



출처: https://www.overtop.co.kr/233 [AWSin]

 

 

+ Recent posts