mstsc shadow:2
mstsc shadow:2
ssd smart path
https://blogs.technet.microsoft.com/koalra/2012/01/15/30-windows-server-51/
http://www.overtop.co.kr/136
가용성 그룹에 대한 읽기 전용 라우팅 구성(SQL Server)
Configure Read-Only Routing for an Availability Group
https://msdn.microsoft.com/library/hh710054.aspx
읽기전용 라우팅을 언제 사용해야 적절할까는 고민할 부분이다.
[환경]
AG1㈜, AG2(보조), AG3(보조) 의 복제복이 존재한다.
[Action Plan]
A. 필수 구성 요소
가용성 그룹 수신기 있어야 한다.
읽기전용 보조 복제복이 있어야 한다.
B. 적용은 T-SQL 또는 PowerShell 로만 적용이 가능하다.
-- 1. 읽기전용 라우팅 설정 하기
/*
읽기전용이란 이름으로 정의하였기 때문에 보조복제본의 연결은 모두 ALL 이 아닌 READ_ONLY 이어야 한다.
아래 설정변경은 주복제본에서만 수행이 된다.
*/
use master
go
ALTER AVAILABILITY GROUP AGName
MODIFY REPLICA ON N'AG1' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = READ_ONLY))
ALTER AVAILABILITY GROUP AGName
MODIFY REPLICA ON N'AG2' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = READ_ONLY))
ALTER AVAILABILITY GROUP AGName
MODIFY REPLICA ON N'AG3' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = READ_ONLY))
ALTER AVAILABILITY GROUP AGName
MODIFY REPLICA ON
N'AG1' WITH
(SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://AG1.overtop.local:1433'));
ALTER AVAILABILITY GROUP AGName
MODIFY REPLICA ON
N'AG2' WITH
(SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://AG2.overtop.local:1433'));
ALTER AVAILABILITY GROUP AGName
MODIFY REPLICA ON
N'AG3' WITH
(SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://AG3.overtop.local:1433'));
ALTER AVAILABILITY GROUP AGName
MODIFY REPLICA ON
N'AG1' WITH
(PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('AG2','AG3','AG1')));
-- AG1 이 주 복제본일경우에 라우팅은 AG3 로 연결되며, AG3 가 접속이 안되는 경우에는 AG2 로 자동연결 된다.
ALTER AVAILABILITY GROUP AGName
MODIFY REPLICA ON
N'AG2' WITH
(PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('AG3','AG1','AG2')));
ALTER AVAILABILITY GROUP AGName
MODIFY REPLICA ON
N'AG3' WITH
(PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('AG1','AG2','AG3')));
GO
-- 2. 설정 확인하기.
SELECT * FROM sys.availability_read_only_routing_lists
GO
SELECT ag.name as "Availability Group", ar.replica_server_name as "When Primary Replica Is",
rl.routing_priority as "Routing Priority", ar2.replica_server_name as "RO Routed To",
ar.secondary_role_allow_connections_desc, ar2.read_only_routing_url
FROM sys.availability_read_only_routing_lists rl
inner join sys.availability_replicas ar on rl.replica_id = ar.replica_id
inner join sys.availability_replicas ar2 on rl.read_only_replica_id = ar2.replica_id
inner join sys.availability_groups ag on ar.group_id = ag.group_id
ORDER BY ag.name, ar.replica_server_name, rl.routing_priority
C. 라우팅 연결 테스트
-K , -d 옵션을 필수 입력해야 확인이 가능하다.
주 복제본에 따라 라우팅 순서를 정의할 수 있다. 위 코드 상에서 AG2가 주 복제복일경우에는 AG3 리턴한다.
sqlcmd -S Aglistener.overtop.local,62000 -E -K ReadOnly -d AGDB1 -Q "select @@servername"
[참고문서]
Modifying AlwaysOn Read Only Routing Lists
http://blogs.msdn.com/b/alwaysonpro/archive/2014/01/22/modifying-alwayson-read-only-routing-lists.aspx
192.168.137.5에 연결하는 중...
메시지 41158, 수준 16, 상태 3, 줄 65
로컬 가용성 복제본을 가용성 그룹 'poc_ag'에 조인하지 못했습니다. 작업 중 SQL Server 오류 41106이(가) 발생하여 작업이 롤백되었습니다. 자세한 내용은 SQL Server 오류 로그를 확인하십시오. 나중에 오류 원인을 해결한 후 ALTER AVAILABILITY GROUP JOIN 명령을 다시 시도하십시오.
192.168.137.5에서 연결을 끊는 중...
쿼럼 구성
클라이언트가 ad 도메인에 없을경우
클라이언트의 host 에 도메인 이름을 명시적으로 쓰던지
아래와 같이 리스너 구성을 명시적으로 ip 를 기술한다.
ALTER AVAILABILITY GROUP poc_ag
MODIFY REPLICA ON N'mhv1' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = READ_ONLY))
ALTER AVAILABILITY GROUP poc_ag
MODIFY REPLICA ON N'mhv2' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = READ_ONLY))
ALTER AVAILABILITY GROUP poc_ag
MODIFY REPLICA ON N'chv1' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = READ_ONLY))
ALTER AVAILABILITY GROUP poc_ag
MODIFY REPLICA ON
N'mhv1' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://192.168.137.4:1433'));
ALTER AVAILABILITY GROUP poc_ag
MODIFY REPLICA ON
N'mhv2' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://192.168.137.5:1433'));
ALTER AVAILABILITY GROUP poc_ag
MODIFY REPLICA ON
N'chv1' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://192.168.137.6:1433'));
ALTER AVAILABILITY GROUP poc_ag
MODIFY REPLICA ON
N'mhv1' WITH
(PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('chv1','mhv2','mhv1')));
-- AG1 이 주 복제본일경우에 라우팅은 AG3 로 연결되며, AG3 가 접속이 안되는 경우에는 AG2 로 자동연결 된다.
ALTER AVAILABILITY GROUP poc_ag
MODIFY REPLICA ON
N'mhv2' WITH
(PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('chv1','mhv1','mhv2')));
ALTER AVAILABILITY GROUP poc_ag
MODIFY REPLICA ON
N'chv1' WITH
(PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('mhv2','mhv1','chv1')));
GO
jdbc test
package com.company;
import java.sql.*;
public class Main {
public static void RunQuery() throws ClassNotFoundException, SQLException, InterruptedException
{
String url = "jdbc:sqlserver://192.168.137.44;DatabaseName=cafedb;ApplicationIntent=ReadOnly";
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
conn = DriverManager.getConnection(url, "test", "1234!@#$");
stmt = conn.createStatement();
rs = stmt.executeQuery("select @@servername ServerName");
rs.next();
System.out.println(rs.getString("ServerName"));
Thread.sleep(500);
rs.close();
stmt.close();
conn.close();
}
public static void main(String[] args)
{
Integer i = 0;
while (1 == 1)
{
i++;
try
{
Main.RunQuery();
System.out.println(i);
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
}
10퍼센트 처리되었습니다.
20퍼센트 처리되었습니다.
30퍼센트 처리되었습니다.
40퍼센트 처리되었습니다.
50퍼센트 처리되었습니다.
60퍼센트 처리되었습니다.
70퍼센트 처리되었습니다.
80퍼센트 처리되었습니다.
90퍼센트 처리되었습니다.
100퍼센트 처리되었습니다.
파일 1에서 데이터베이스 'userDatabase', 파일 'userDatabase_Data'에 대해 0개의 페이지를 처리했습니다 .
파일 1에서 데이터베이스 'userDatabase', 파일 'userDatabase_Data2'에 대해 0개의 페이지를 처리했습니다 .
파일 1에서 데이터베이스 'userDatabase', 파일 'userDatabase_Data3'에 대해 0개의 페이지를 처리했습니다 .
파일 1에서 데이터베이스 'userDatabase', 파일 'userDatabase_GUEST'에 대해 0개의 페이지를 처리했습니다 .
파일 1에서 데이터베이스 'userDatabase', 파일 'userDatabase_z1'에 대해 0개의 페이지를 처리했습니다 .
파일 1에서 데이터베이스 'userDatabase', 파일 'userDatabase_Log'에 대해 234355개의 페이지를 처리했습니다 .
메시지 3456, 수준 16, 상태 1, 줄 1
페이지 (1:828275), 데이터베이스 'userDatabase'(데이터베이스 ID 5)에서 트랜잭션 ID (16:395253956)에 대한 로그 레코드 (3529369:96028:38)을(를) 다시 실행할 수 없습니다. 페이지: LSN = (3529369:95946:19), 유형 = 2. 로그: OpCode = 3, 컨텍스트 19, PrevPageLSN: (3529369:95244:5). 데이터베이스 백업에서 복원하거나 데이터베이스를 복구하십시오.
메시지 9004, 수준 16, 상태 6, 줄 1
데이터베이스 'userDatabase'의 로그를 처리하는 동안 오류가 발생했습니다. 가능하면 백업을 사용하여 복원하십시오. 백업이 없을 경우 로그를 다시 만들어야 합니다.
메시지 3013, 수준 16, 상태 1, 줄 1
RESTORE LOG이(가) 비정상적으로 종료됩니다.
내용을 보니 현재 처리중인 LSN (3529369:95946:19) 과 이전 LSN (3529369:95244:5) 이 맞지 않아 나는 에러인데....왜 이런 현상이 일어나는지는 이해할 수 없네...
테스트가 필요한 부분은 데이터베이스 커럽션이 있는지
차등백업 후 로그백업을 복구하면 에러없이 진행 가능한지 등이 있겠다.
최후의 수단으로 CONTINUE_AFTER_ERROR 가 있을 수 있다.
읽어볼만한 글
http://dba.stackexchange.com/questions/93473/unable-to-restore-error-3456
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/36dd0107-ceca-4d48-8523-3c5624c135b2/msg-3456-level-16-state-1-could-not-redo-log-record?forum=sqldatabaseengine
https://www.mssqltips.com/sqlservertip/3209/understanding-sql-server-log-sequence-numbers-for-backups/
복사본
In order to understanding why error 3456 would be thrown, we need to take a little step back and understand how SQL Server handles this corner of recovery.
When SQL Server is redoing an operation, and that redo is a page modification, it makes a quick check. In the page header there is ultimately going to be a PageLSN
, which is an indication of the last LSN that has modified that page, recorded by the page. Think about it like this, the page keeps track of the last LSN that has made modifications to it. This is the PageLSN
.
Every time there is a logged page modification operation, that log record includes a few LSNs. Namely, the log record's LSN (think... Current LSN), and then it has what's called the Previous Page LSN (PrevPageLSN
going forward). So when we modify a page, one of the pieces of data that is put into the log record is what the page indicates as being the last LSN before you to have modified the page.
Think about it like this... Your car needs to have work done on it. Mechanic John works on your car, and in the engine bay it has a little tag and Mechanic John writes "John worked on this car last". Then the next time you take your car in to another shop, Mechanic Mark looks in the engine bay and sees that Mechanic John worked on this car last. On his data sheet he writes this information. Same idea with SQL Server.
This can be somewhat confusing, so take a look at this image below on sequential page modifications, and how the PageLSN
and PrevPageLSN
relate:
Let's loop back around, as this all comes into play when you need to redo an operation on a page (restores, recovery, HA, etc.). When SQL Server needs to redo a page operation, it makes a sanity check to see if the PageLSN
on the page matches the PrevPageLSN
that the log record includes. If that is not equal, then you will see error 3456 get thrown.
Let's analyze your error message, which includes the how:
Could not redo log record (210388:123648:232), for transaction ID (0:1016710921), on page (4:8088), database 'SomeDB' (database ID 6). Page: LSN = (0:0:1), type = 11. Log: OpCode = 4, context 11, PrevPageLSN: (210388:122007:1). Restore from a backup of the database, or repair the database. Msg 3013, Level 16, State 1, Line 1 RESTORE LOG is terminating abnormally.
I have bold'd the two pieces of data that have an inequality causing the error. You can see that our PageLSN
is 0:0:1 (this was found in the page's header), and our PrevPageLSN
is 210388:122007:1(this was found in the data on the log record that was attempting to be redone). These are obviously not equal, hence err3456.
So in order to find out the why of this event, would be to find out why there is a disparity here. We really need to trace the lifecycle of page 4:8088 and see where the disconnect is. Unfortunately without further information, or hands-on troubleshooting there isn't much else I can do besides give you the background of this recovery operation and what causes the error.
This tip describes SQL Server Log Sequence Numbers (LSNs) and how the sequence numbers link full, differential and transaction log backups. We will look at sample backups and how these LSN values can be read from the backup files to determine the restore path.
This tip is the continuation from this tip, Different Ways to Restore a SQL Server Database, and utilizes the same database creation and backup scripts to explain how the SQL Server full, differential and transaction log backup chain is mapped between each backup type. If you want to follow along, please read this first tip and setup your database and backups.
When restoring a database, the initial database RESTORE sequence must begin from a FULL database backup. A database RESTORE sequence cannot begin with a differential file backup or transaction log backup. When restoring databases there are four important LSNs: FirstLSN, LastLSN, CheckpointLSN and DatabaseBackupLSN. These values can be retrieved from a SQL Server backup file using the RESTORE HEADERONLY command.
You can use RESTORE HEADERONLY to retrieve the backup header information for each backup file on disk as shown below.
USE [master] RESTORE HEADERONLY FROM DISK = N'C:\Temp\F1.BAK' RESTORE HEADERONLY FROM DISK = N'C:\Temp\T1.TRN' RESTORE HEADERONLY FROM DISK = N'C:\Temp\T2.TRN' RESTORE HEADERONLY FROM DISK = N'C:\Temp\D1.BAK'
I have collated the FirstLSN, LastLSN, CheckpointLSN and DatabaseBackupLSN for these database backup files (Database setup script) into an Excel spreadsheet as shown below. The full scripts to retrieve the LSNs from all backup files are found at the end of this tip.
"Column A" is the backup type performed at a point-in-time (i.e. F1 = first full backup, T3 = third transaction log backup, D2 = second differential backup).
Some attributes for the full database backup LSNs are:
Some attributes of a differential database backup LSNs are:
Some attributes of a transaction log backup LSNs are:
Below are 3 sections that describe the LSN mapping for:
This is the full script to retrieve the LSNs for all database backup files created from this tip.
USE [master] RESTORE HEADERONLY FROM DISK = N'C:\Temp\F1.BAK' RESTORE HEADERONLY FROM DISK = N'C:\Temp\T1.TRN' RESTORE HEADERONLY FROM DISK = N'C:\Temp\T2.TRN' RESTORE HEADERONLY FROM DISK = N'C:\Temp\D1.BAK' RESTORE HEADERONLY FROM DISK = N'C:\Temp\T3.TRN' RESTORE HEADERONLY FROM DISK = N'C:\Temp\T4.TRN' RESTORE HEADERONLY FROM DISK = N'C:\Temp\D2.BAK' RESTORE HEADERONLY FROM DISK = N'C:\Temp\T5.TRN' RESTORE HEADERONLY FROM DISK = N'C:\Temp\F2.BAK' RESTORE HEADERONLY FROM DISK = N'C:\Temp\T6.TRN' RESTORE HEADERONLY FROM DISK = N'C:\Temp\T7.TRN' RESTORE HEADERONLY FROM DISK = N'C:\Temp\D3.BAK' RESTORE HEADERONLY FROM DISK = N'C:\Temp\T8.TRN'
bios 에서 vt-x 를 enable 해도 위 첨부 파일로 조사시 Hardware Virtualization 이 No 로 나타나면 virtual box 가 동작하지 않는다. 그러므로, 아래 명령어로 hyper-v 를 disable 하고 리부팅 한다.
Hypwer V 가 enable 되어 있으면 Oracle Virtual Box 가 동작하지 않는 이슈가 있음 ㅠ.ㅠ
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V –All
Disable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All