PHP 대기 열 필드 및 구현 코드 인 스 턴 스 상세 설명

9805 단어 PHP대열
단점 의 압력 을 낮 추기 위해 통상 적 으로 업무 상황 에 따라 표 분 고 를 하고 표를 서로 다른 라 이브 러 리 에 분포 한다(라 이브 러 리 는 서로 다른 기계 에 분포 할 수 있다).그러나 하나의 업무 장면 은 두 표 의 조작 을 동시에 처리 할 수 있다.이러한 장면 에서 업무 의 제출 은 상대 적 으로 복잡 해 집 니 다.여러 노드(라 이브 러 리)가 존재 하기 때문에 일부 노드 가 제출 에 실패 하 는 상황 이 존재 할 수 있 습 니 다.즉,업무 의 ACID 특성 은 서로 다른 데이터 베이스 인 스 턴 스 에서 보증 해 야 합 니 다.예 를 들 어 db1 라 이브 러 리 의 A 표를 업데이트 할 때 db2 라 이브 러 리 의 B 표를 동시에 업데이트 해 야 합 니 다.두 개의 업 데 이 트 는 하나의 사 무 를 형성 하거나 모두 성공 하거나 실 패 했 습 니 다.
그렇다면 우 리 는 어떻게 my sql 을 이용 하여 분포 식 데이터 베 이 스 를 실현 합 니까?
my sql 은 5.0 부터 분포 식 사 무 를 지원 합 니 다.
여기 서 먼저 두 가지 개념 을 성명 한다.
자원 관리자(resource manager):시스템 자원 을 관리 하 는 것 은 사무 자원 으로 통 하 는 경로 입 니 다.데이터 베 이 스 는 일종 의 자원 관리자 다.자원 관 리 는 업무 제출 이나 스크롤 백 을 관리 하 는 능력 도 있어 야 한다.
트 랜 잭 션 관리자(transaction manager):트 랜 잭 션 관리 자 는 분포 식 트 랜 잭 션 의 핵심 관리자 입 니 다.트 랜 잭 션 관리자 와 모든 자원 관리자(resource
manager)통신 을 하고 업무 처 리 를 조율 하 며 완성 합 니 다.트 랜 잭 션 의 각 가 지 는 유일한 이름 으로 표 시 됩 니 다.
my sql 분포 식 트 랜 잭 션(외부 XA)을 실행 할 때 my sql 서버 는 xa 트 랜 잭 션 자원 관리자 에 해당 하 며,my sql 링크 클 라 이언 트 와 트 랜 잭 션 관리자 에 해당 합 니 다.
분산 식 트 랜 잭 션 원리:세그먼트 제출
분산 사 무 는 보통 2PC 프로 토 콜 을 사용 하 는데 전 칭Two Phase Commitment Protocol을 사용한다.이 협 의 는 주로 분포 식 데이터 베이스 장면 에서 모든 노드 간 데이터 일치 성 문 제 를 해결 하기 위해 서 이다.분산 사 무 는 2PC 프로 토 콜 을 통 해 제출 을 두 단계 로 나 눌 것 입 니 다.
prepare;commit/rollback
단계 1 준비(prepare)단계.모든 참여 자 들 이 업 무 를 수행 하고 필요 한 자원 을 잠 그 려 고 하 는 것 이다.참여 자 ready 시 transaction manager 에 보고 할 준비 가 되 어 있 습 니 다.
단계 2 는 제출 단계(commt)입 니 다.transaction manager 가 모든 참여 자 에 게 ready 를 확인 한 후 모든 참여 자 에 게 commt 명령 을 보 냅 니 다.
트 랜 잭 션 관리자
XA 사 무 는 2 단계 로 협 의 를 제출 하기 때문에 모든 사무 참여 자가 준비 작업(1 단계)을 마 칠 수 있 도록 사무 코 디 네 이 터(transaction manager)가 필요 합 니 다.트 랜 잭 션 코 디 네 이 터(transaction manager)가 모든 참여 자가 준비 한 메 시 지 를 받 으 면 모든 트 랜 잭 션 을 제출 할 수 있다 고 알려 줍 니 다(2 단계).MySQL 은 이 XA 사무 에서 트 랜 잭 션 코 디 네 이 터(transaction manager)가 아 닌 참여 자의 역할 을 맡 았 다.
Mysql 의 XA 업 무 는 외부 XA 와 내부 XA 로 나 뉜 다.
외부 XA 는 다 중 MySQL 인 스 턴 스 를 뛰 어 넘 는 분포 식 사무 에 사용 되 므 로 응용 층 을 코 디 네 이 터 로 해 야 합 니 다.쉽게 말 하면 우리 가 PHP 에서 코드 를 쓰 면 PHP 가 쓰 는 논 리 는 코 디 네 이 터 입 니 다.응용 층 은 제출 할 지 스크롤 백 할 지,붕 괴 될 때의 행 잉 업 무 를 결정 합 니 다.MySQL 데이터베이스 외부 XA 는 분포 식 데이터베이스 에이전트 층 에 사용 하여 MySQL 데이터베이스 에 대한 분포 식 사무 지원 을 실현 할 수 있 습 니 다.예 를 들 어 오픈 소스 의 에이전트:왕 이의 DDB,타 오 바 오의 TDDL 등 입 니 다.
내부 XA 사 무 는 같은 인 스 턴 스 에서 다 중 엔진 사 무 를 수행 하 는 데 사 용 됩 니 다.예 를 들 어 하나의 저장 엔진 이 제출 할 때 제출 정 보 를 바 이 너 리 로그 에 기록 해 야 합 니 다.이것 은 분포 식 내부 XA 사무 입 니 다.바 이 너 리 로그 의 참여 자 는 MySQL 본체 일 뿐 입 니 다.Binlog 는 내부 XA 의 코 디 네 이 터 로 서 binlog 에 나타 난 내부 xid 는 crash recover 시 binlog 가 책임 지고 제출 합 니 다.(이 는 binlog 가 prepare 를 하지 않 고 commt 만 진행 하기 때문에 binlog 에 나타 난 내부 xid 는 바 텀 각 저장 엔진 에서 prepare 를 완성 했다 는 것 을 보증 할 수 있 습 니 다).
mysql xa 사무 문법
1.우선 my sql 에서 XA 트 랜 잭 션 지원 을 확보 해 야 합 니 다.

SHOW VARIABLES LIKE '%xa%'
innodb_support_xa의 값 이 ON 이 라면 my sql 이 XA 사무 에 대한 지원 을 시 작 했 음 을 나타 낸다.아니면 실행:

SET innodb_support_xa = ON
주로:

XA START 'any_unique_id'; // 'any_unique_id'      ,       mysql     XA  
XA END 'any_unique_id '; //  XA       
XA PREPARE 'any_unique_id'; //  mysql       xa  
XA COMMIT 'any_unique_id'; //  mysql    xa  
XA ROLLBACK 'any_unique_id'; //  mysql    xa  
XA RECOVER;//    mysql     xa    prepare  
XA 트 랜 잭 션 복구
분포 식 사 무 를 수행 하 는 my sql crash 가 발생 하면 my sql 은 다음 과 같은 논리 로 복 구 됩 니 다.
a.만약 이 xa 사무 commt 가 된다 면 아무것도 할 필요 가 없습니다.
b.이 xa 업무 가 아직 준비 되 지 않 았 다 면 바로 스크롤 백 합 니 다.
c.이 xa 사무 prepare 가 아직 commt 가 없다 면 prepare 상태 로 복원 하고 사용자 가 commt 나 rollback 을 결정 합 니 다.
mysql 충돌 후 다시 시작 하면"XA RECOVER;"를 실행 합 니 다.현재 prepare 상태 에 있 는 xa 사 무 를 보고 commt 나 rollback 을 보십시오.
사용 제한
a.XA 사무 와 로 컬 사무 및 잠 금 표 작업 은 서로 배척 합 니 다.
xa 트 랜 잭 션 을 열 면 로 컬 트 랜 잭 션 과 잠 금 표를 사용 할 수 없습니다.

mysql> xa start 't1xa';
Query OK, 0 rows affected (0.04 sec)
mysql> begin;
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state
mysql> lock table t1 read;
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state
로 컬 트 랜 잭 션 을 시작 하면 xa 트 랜 잭 션 을 사용 할 수 없습니다.

mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> xa start 'rrrr';
ERROR 1400 (XAE09): XAER_OUTSIDE: Some work is done outside global transaction
b. xa start이후 에는 반드시xa end해 야 하 며,그렇지 않 으 면 집행 할 수 없다xa commitxa rollback그래서 xa 사 무 를 수행 하 는 과정 에서 문구 가 잘못 되 었 다 면 당신 도 먼저xa end한 번 해 야xarollback할 수 있 습 니 다.
주의 사항
a.my sql 은 xa 업무 의 인 터 페 이 스 를 제공 할 뿐 분포 식 업무 중의 my sql 인 스 턴 스 는 서로 독립 적 으로 감지 되 지 않 습 니 다.그래서 사용 자 는 분포 식 트 랜 잭 션 스케줄 러 를 스스로 실현 해 야 합 니 다.
b.xa 사무 에 사용 되 는 bug 가 있 습 니 다.참고 하 십시오.http://www.mysqlops.com/2012/02/24/mysql-xa-optimize.html
주로
"MySQL 데이터베이스 의 주 데이터베이스 동기 화 는 Binlog 의 복 제 를 통 해 이 루어 집 니 다.한편,Binlog 는 MySQL 데이터베이스 내부 XA 업무 의 코 디 네 이 터 이 고 MySQL 데이터 베 이 스 는 binlog 에 최적화 되 었 습 니 다.-binlog 는 prepare 로 그 를 쓰 지 않 고 commt 로그 만 씁 니 다.
모든 참여 노드 prepare 가 완료 되 었 습 니 다.xa commit 전에 crash 를 진행 합 니 다.crash recover.commt 를 선택 하면binlog 가 prepare 단계 에 쓰 이지 않 았 기 때문에 메 인 라 이브 러 리 에서 볼 때 이 분포 식 사 무 는 최종 적 으로 제출 되 었 으 나 이 업무 의 조작 은 binlog 에 쓰 이지 않 았 기 때문에 예비 라 이브 러 리 에 복사 되 지 못 해 메 인 라 이브 러 리 데이터 가 일치 하지 않 는 상황 이 발생 했 습 니 다.
한편,crash recover 는 rollback 을 선택 하면 전체 국면 이 일치 하지 않 습 니 다."최종 적 으로 같은 분포 식 사 무 를 초래 하고 각 참여 노드 에서 최종 상태 가 일치 하지 않 습 니 다)"
참고 한 블 로그 에서 제시 한 방법 은 mysql 코드 를 수정 하 는 것 입 니 다.이것 은 DBScale 에서 사용 할 수 없습니다.그래서 선택 할 수 있 는 대안 은 사용 하지 않 습 니 다.
복사 에서 백업 을 하 는 것 이 아니 라 xa 사 무 를 직접 사용 하여 동기 화 기록 을 백업 합 니 다.
php+mysql 분포 식 사무 사례 실현
데이터 시트 가 innodb 임 을 보증 합 니 다.

//db_finance  
CREATE TABLE `t_user_account` (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
 `username` varchar(255) NOT NULL DEFAULT '' COMMENT '   ',
 `money` int(11) NOT NULL DEFAULT '0' COMMENT '    ',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

//db_order  
CREATE TABLE `t_user_orders` (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '  ',
 `username` varchar(255) NOT NULL DEFAULT '',
 `money` int(11) NOT NULL DEFAULT '0' COMMENT '      ',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8;
php 코드

$username = '   PHP    ';
$order_money = 100;

$addOrder_success = addOrder($username,$order_money);
$upAccount_success = updateAccount($username,$order_money);


if($addOrder_success['state'] =="yes" && $upAccount_success['state']=="yes"){
  commitdb($addOrder_success['xa']);
  commitdb1($upAccount_success['xa']);
}else{
  rollbackdb($addOrder_success['xa']);
  rollbackdb1($upAccount_success['xa']);
}
die;
function addOrder ($username, $order_money){

  $xa = uniqid("");

  $sql_xa = "XA START '$xa'";
  $db = Yii::app()->dborder_readonly;
  $db->createCommand($sql_xa)->execute();

  $insert_sql = "INSERT INTO t_user_orders (`username`,`money`) VALUES ($username,$order_money)";
  $id = $db->createCommand($insert_sql)->execute();

  $db->createCommand("XA END '$xa'")->execute();
  if ($id) {

    $db->createCommand("XA PREPARE '$xa'")->execute();
    return ['state' => 'yes', 'xa' => $xa];
  }else {
    return ['state' => 'no', 'xa' => $xa];
  }

}

function updateAccount($username, $order_money){
  $xa = uniqid("");
  $sql_xa = "XA START '$xa'";
  $db = Yii::app()->db_finance;
  $db->createCommand($sql_xa)->execute();

  $sql = "update t_user_account set money=money-".$order_money." where username='$username'";


  $id = $db->createCommand($sql)->execute();

  $db->createCommand("XA END '$xa'")->execute();
  if ($id) {
    $db->createCommand("XA PREPARE '$xa'")->execute();
    return ['state' => 'yes', 'xa' => $xa];
  }else {
    return ['state' => 'no', 'xa' => $xa];
  }

}


//    !
function commitdb($xa){

  $db = Yii::app()->dborder_readonly;
  return $db->createCommand("XA COMMIT '$xa'")->execute();
}

//    
function rollbackdb($xa){

  $db = Yii::app()->dborder_readonly;
  return $db->createCommand("XA COMMIT '$xa'")->execute();
}

//    !
function commitdb1($xa){

  $db = Yii::app()->db_finance;
  return $db->createCommand("XA COMMIT '$xa'")->execute();

}
//    
function rollbackdb1($xa){
  $db = Yii::app()->db_finance;
  return $db->createCommand("XA ROLLBACK '$xa'")->execute();
PHP 대기 열 장면 과 구현 코드 인 스 턴 스 에 대한 자세 한 설명 은 여기까지 입 니 다.더 많은 관련 PHP 대기 열 장면 과 구현 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 지원 바 랍 니 다!

좋은 웹페이지 즐겨찾기