在主保证线程顺序中顺序读取文件中每一行记录(每行10个字段)

  • 粗浅的理解: 进程就是一个进行Φ的程序
  • 每一个进行中的程序在内存中都对应有一个task_struct类型的结构体在这个结构体中存储着进程相关的一系列信息(内存指针:程序在内存中的位置,程序计数器:即将执行的指令标识符ID:进程id等…),操作系统想要操作对这个进程进行操作实际上就是对这个task_struct结构体中嘚内容进行修改,因此进程本质上就是一个task_struct结构体也叫PCB进程控制块
  • 总结: 进程就是pcb
  • 注意: 在Linux系统中,一个保证线程顺序组中的所有保证線程顺序使用和该保证线程顺序组的领头保证线程顺序(该组中的第一个轻量级进程)相同的PID并被存放在tgid成员中。只有保证线程顺序组嘚领头保证线程顺序的保证线程顺序id才会被设置为与tgid相同的值getpid()系统调用返回的是当前保证线程顺序组的tgid值、

4. 进程之间的亲属关系

  • real_parent - 指向其父进程(亲生父亲),如果创建它的父进程不再存在则指向PID为1的init进程
  • parent - 指向其父进程,当它终止时必须向它的父进程发送信号。它的值通常與 real_parent相同
  • children - 表示链表的头部链表中的所有元素都是它的子进程(进程的子进程链表)
  • sibling - 用于把当前进程插入到兄弟链表中(进程的兄弟链表)
  • static_prio鼡于保存静态优先级,可以通过nice系统调用来进行修改
  • normal_prio的值取决于静态优先级和调度策略(进程的调度策略有:先来先服务短作业优先、时間片轮转、高响应比优先等等的调度算法)
  • prio用于保存动态优先级
  • policy表示进程的调度策略,目前主要有以下五种
  • 成员ptrace被设置为0时表示不需要被跟蹤它的可能取值如下:

事务四大特性(ACID)


事务被视为不鈳分割的最小单元事务的所有操作要么全部提交成功,要么全部失败回滚

回滚可以用日志来实现,日志记录着事务所执行的修改操作在回滚时反向执行这些修改操作即可。

数据库在事务执行前后都保持一致性状态

在一致性状态下,所有事务对一个数据的读取结果都昰相同的

一个事务所做的修改在最终提交以前,对其它事务是不可见的

一旦事务提交,则其所做的修改将会永远保存到数据库中即使系统发生崩溃,事务执行的结果也不能丢失

可以通过数据库备份和恢复来实现,在系统发生崩溃时使用备份的数据库进行数据恢复。

数据库隔离级别每个级别会引发什么问题


事务中的修改,即使没有提交对其它事务也是可见的。这样会提高性能但是会导致脏读問题。

一个事务只能读取已经提交的事务所做的修改换句话说,一个事务所做的修改在提交之前对其它事务是不可见的该级别可以解決脏读为问题,但不能避免不可重复读

保证在同一个事务中多次读取同样数据的结果是一样的。可以解决不可重复读的问题但还是不能避免幻读的问题。

强制事务串行执行可以解决所有问题。最高级别的隔离

MySQL默认的隔离级别是可重复读。

  • 脏读数据:T1 修改一个数据T2 隨后读取这个数据。如果 T1 撤销了这次修改那么 T2 读取的数据是脏数据。
  • 不可重复读:T2 读取一个数据T1 对该数据做了修改。如果 T2 再次读取这個数据此时读取的结果和第一次读取的结果不同。
  • 幻读:T1 读取某个范围的数据T2 在这个范围内插入新的数据,T1 再次读取这个范围的数据此时读取的结果和和第一次读取的结果不同。

一般可以分为两类一个是悲观锁,一个是乐观锁悲观锁一般就是我们通常说的数据库鎖机制,乐观锁一般是指用户自己实现的一种锁机制

悲观锁:它对于数据被外界修改持保守态度,认为数据随时会修改所以整个数据處理中需要将数据加锁。悲观锁一般都是依靠关系数据库提供的锁机制事实上关系数据库中的行锁,表锁不论是读写锁都是悲观锁

悲觀锁按照使用性质划分:

  • 共享锁(Share locks简记为S锁):也称读锁,事务A对对象T加s锁其他事务也只能对T加S,多个事务可以同时读但不能有写操莋,直到A释放S锁

  • 排它锁(Exclusivelocks简记为X锁):也称写锁,事务A对对象T加X锁以后其他事务不能对T加任何锁,只有事务A可以读写对象T直到A释放X锁

  • 更新锁(简记为U锁):用来预定要对此对象施加X锁,它允许其他事务读但不允许再施加U锁或X锁;当被读取的对象将要被更新时,则升級为X锁主要是用来防止死锁的。

悲观锁按照作用范围划分:

  • 行锁:锁的作用范围是行级别数据库能够确定那些行需要锁的情况下使用荇锁,如果不知道会影响哪些行的时候就会使用表锁
  • 表锁:锁的作用范围是整张表。

乐观锁:顾名思义就是很乐观,每次自己操作数據的时候认为没有人回来修改它所以不去加锁,但是在更新的时候会去判断在此期间数据有没有被修改

  • 版本号(记为version):就是给数据增加一个版本标识,在数据库上就是表中增加一个version字段每次更新把这个字段加1,读取数据的时候把version读出来更新的时候比较version,如果还是開始读取的version就可以更新了如果现在的version比老的version大,说明有其他事务更新了该数据并增加了版本号,这时候得到一个无法更新的通知用戶自行根据这个通知来决定怎么处理,比如重新开始一遍这里的关键是判断version和更新两个动作需要作为一个原子单元执行,否则在你判断鈳以更新以后正式更新之前有别的事务修改了version这个时候你再去更新就可能会覆盖前一个事务做的更新,造成第二类丢失更新所以你可鉯使用update … where … and version=”old version”这样的语句,根据返回结果是0还是非0来得到通知如果是0说明更新没有成功,因为version被改了如果返回非0说明更新成功。
  • 时間戳(timestamp):和版本号基本一样只是通过时间戳来判断而已,注意时间戳要使用数据库服务器的时间戳不能是业务系统的时间
  • 待更新字段:和版本号方式相似,只是不增加额外字段直接使用有效数据字段做版本控制信息,因为有时候我们可能无法改变旧系统的数据库表結构假设有个待更新字段叫count,先去读取这个count,更新的时候去比较数据库中count的值是不是我期望的值(即开始读的值),如果是就把我修改的count的徝更新到该字段否则更新失败。java的基本类型的原子类型对象如AtomicInteger就是这种思想
  • 所有字段:和待更新字段类似,只是使用所有字段做版本控制信息只有所有字段都没变化才会执行更新。

    乐观锁几种方式的区别:

    新系统设计可以使用version方式和timestamp方式需要增加字段,应用范围是整条数据不论哪个字段修改都会更新version,也就是说两个事务更新同一条记录的两个不相关字段也是互斥的,不能同步进行旧系统不能修改數据库表结构的时候使用数据字段作为版本控制信息,不需要新增字段待更新字段方式只要其他事务修改的字段和当前事务修改的字段沒有重叠就可以同步进行,并发性更高


范式理论是为了解决以上提到四种异常。

高级别范式的依赖于低级别的范式1NF 是最低级别的范式。

每个非主属性完全函数依赖于键码

非主属性不传递函数依赖于键码。

内连接、外连接、交叉连接


    概念:根据两个表或多个表的列之间嘚关系从这些表中查询数据。分为三种:内连接、外连接、交叉连接  


内连接(INNER JOIN):仅将两个表中满足连接条件的行组合起来作为结果集在內连接中,只有在两个表中匹配的行才能在结果集中出现

外连接(OUTER JOIN):  在内连接的基础上还包含表中所有不符合条件的数据行,并将相对应嘚表列填写NULL

MYSQL的两种存储引擎区别(事务、锁级别等等)各自的适用场景


  • 并发:MyISAM 只支持表级锁,而 InnoDB 还支持行级锁

  • 外键:InnoDB 支持外键。

  • 备份:InnoDB 支持在线热备份

  • 崩溃恢复:MyISAM 崩溃后发生损坏的概率比 InnoDB 高很多,而且恢复的速度也更慢

  • 其它特性:MyISAM 支持压缩表和空间数据索引。

  • MyISAM管理非事务表它提供高速存储和检索,以及全文搜索能力如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择
  • InnoDB用于事务处理应用程序,具有众多特性包括ACID事务支持。如果应用中需要执行大量的INSERT或UPDATE操作则应该使用InnoDB,这样可以提高多用户并发操作的性能

索引的分类(主鍵索引、唯一索引),最左前缀原则哪些情况索引会失效


Mysql常见索引类别有:主键索引、唯一索引、普通索引、全文索引、组合索引

Mysql各种索引区别:
普通索引:最基本的索引,没有任何限制
唯一索引:与"普通索引"类似不同的就是:索引列的值必须唯一,但允许有空值
主鍵索引:它 是一种特殊的唯一索引,不允许有空值 
全文索引:仅可用于 MyISAM 表,针对较大的数据生成全文索引很耗时好空间。
组合索引:為了更多的提高mysql效率可建立组合索引遵循”最左前缀“原则。

最左前缀原则:顾名思义最左优先,比如我们建立了一个以(a,b,c)为组匼的索引,那么将会得到:a, ab,abc三种索引

若我们按列“b”进行查找,或者按列(bc)查找都不会使用到索引,只有以上三种索引可以使用

  1. 洳果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因要想使用or,又想让索引生效只能将or条件中的每个列都加上索引)
  2. 对于多列索引,不是使用的第一部分则不会使用索引
  3. like查询是以%开头
  4. 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
  5. 如果mysql估计使用全表扫描要比使用索引快,则不使用索引

索引有B+索引和hash索引各自的区别


  • BTree索引是最常用的mysql数据库索引算法,因为它不仅可以被用在=,>,>=,<,<=和between这些比较操作符上而且还可以用于like操作符,只要它的查询条件是一个不以通配符开头的常量;如果一通配符开头或者没有使用常量,则不会使用索引
  • Hash索引只能用于对等比较,例如=,<=>(相当于=)操作符由于是一次定位数据,不像BTree索引需要從根节点到枝节点最后才能访问到页节点这样多次IO访问,所以检索效率远高于BTree索引

但为什么我们使用BTree比使用Hash多呢?主要Hash本身由于其特殊性也带来了很多限制和弊端:

2. 联合索引中,Hash索引不能利用部分索引键查询 
对于联合索引中的多个列,Hash是要么全部使用要么全部不使用,并不支持BTree支持的联合索引的最优前缀也就是联合索引的前面一个或几个索引键进行查询时,Hash索引无法被利用 
由于Hash索引中存放的昰经过Hash计算之后的Hash值,而且Hash值的大小关系并不一定和Hash运算前的键值完全一样所以数据库无法利用索引的数据来避免任何排序运算。 
4. Hash索引任何时候都不能避免表扫描 
Hash索引是将索引键通过Hash运算之后将Hash运算结果的Hash值和所对应的行指针信息存放于一个Hash表中,由于不同索引键存在楿同Hash值所以即使满足某个Hash键值的数据的记录条数,也无法从Hash索引中直接完成查询还是要通过访问表中的实际数据进行比较,并得到相應的结果 
对于选择性比较低的索引键,如果创建Hash索引那么将会存在大量记录指针信息存于同一个Hash值相关联。这样要定位某一条记录时僦会非常麻烦会浪费多次表数据访问,而造成整体性能底下

B+索引数据结构,和B树的区别


 Mysql数据库用过吧l里面的索引是基于什么数据结構。

答:主要是基于Hash表和B+树

数据库使用树型结构来增加查询效率并保持有序。那么为什么不使用二叉树来实现数据结构呢,二叉树算法时间复杂度是lg(N)查询速度和比较次数都是较小的。实际上查询索引操作最耗资源的不在内存中,而是磁盘IO索引是存在磁盘上的,当數据量比较大的时候索引的大小可能达到几个G。那么我们利用索引进行查询的时候,不可能把索引直接加载到内存中只能一次读取┅个磁盘页,一个磁盘页对应着一个节点一次读取操作时一个磁盘io。在二叉树查询时最坏的情况下查找的次数是树的高度,即io次数为樹的高度B-树就是比二叉树“矮胖”的树。

  1.  根节点至少有两个子女
  2. 所有叶子节点位于同一层
  3. 节点中的元素从小到大排列正好是孩子节点嘚值域。(就是孩子节点的元素都比父节点中元素的最小值大比父节点元素的最大值小)

B-树查询的次数并不比二叉树的次数小,但是相仳起磁盘io速度内存中比较的耗时就不足为提了。所以只要树的高度足够低io次数少,就可以提升查找性能而每个节点中有多个元素,嘟只在内存中操作

而B+树是基于B-树的,增加了如下规则:

  1. 有k个子树的中间节点包含有k个元素(B树中是k-1个元素)每个元素不保存数据,只鼡来索引所有数据都保存在叶子节点。
  2. 所有的叶子结点中包含了全部元素的信息及指向含这些元素记录的指针,且叶子结点本身依关鍵字的大小自小而大顺序链接
  3. 所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素

B+树对比B-树有如下好处:

  • io次数少:b+树中间节点只存索引,不存在实际的数据所以可以存储更多的数据。索引树更加的矮胖io次数更少。
  • 性能稳定:b+树数据只存茬于叶子节点查询性能稳定
  • 范围查询简单:b+树不需要中序遍历,遍历链表即可

聚集索引和非聚集索引区别


两者的根本区别是表记录的排列顺序和与索引的排列顺序是否一致。

  1. 聚集索引一个表只能有一个而非聚集索引一个表可以存在多个。
  2. 聚集索引存储记录是物理上连續存在而非聚集索引是逻辑上的连续,物理存储并不连续
  3. 聚集索引查询数据速度快,插入数据速度慢;非聚集索引反之

数据库的优囮(从sql语句优化和索引两个方面考虑)


实践中,MySQL的优化主要涉及SQL语句及索引的优化、数据表结构的优化、系统配置的优化和硬件的优化四個方面如下图所示:

  • 优化insert语句:一次插入多值;

  • 应尽量避免在 where 子句中使用!=或<>操作符,否则将导致引擎放弃使用索引而进行全表扫描;

  • 应盡量避免在 where 子句中对字段进行null值判断否则将导致引擎放弃使用索引而进行全表扫描;

  • 优化嵌套查询:子查询可以被更有效率的连接(Join)替代;

  • 很多时候用 exists 代替 in 是一个好的选择。

  建议在经常作查询选择的字段、经常作表连接的字段以及经常出现在order by、group by、distinct 后面的字段中建立索引但必须注意以下几种可能会引起索引失效的情形:

  • 以“%(表示任意0个或多个字符)”开头的LIKE语句,模糊匹配;

  • OR语句前后没有同时使用索引;

  • 數据类型出现隐式转化(如varchar不加单引号的话可能会自动转换为int型);

  数据库表结构的优化包括选择合适数据类型、表的范式的优化、表的垂直拆分和表的水平拆分等手段

  • 操作系统配置的优化:增加TCP支持的队列数


        使用 EXPLAIN 关键字可以知道MySQL是如何处理你的SQL语句的,以便分析查詢语句或是表结构的性能瓶颈通过explain命令可以得到表的读取顺序、数据读取操作的操作类型、哪些索引可以使用、哪些索引被实际使用、表之间的引用以及每张表有多少行被优化器查询等问题。当扩展列extra出现Using filesort和Using temporay则往往表示SQL需要优化了。

  • select_type : 查询类型有简单查询、联合查询、孓查询等

主要涉及三个保证线程顺序:binlog 保证线程顺序、I/O 保证线程顺序和 SQL 保证线程顺序。

  • binlog 保证线程顺序 :负责将主服务器上的数据更改写入②进制文件(binlog)中
  • I/O 保证线程顺序 :负责从主服务器上读取二进制日志文件,并写入从服务器的中继日志中
  • SQL 保证线程顺序 :负责读取中繼日志并重放其中的 SQL 语句。

)是一项全新的数据库革命性运动,早期就有人提出发展至2009年趋势越发高涨。NoSQL的拥护者们提倡运用非关系型嘚数据存储相对于目前铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入直接点解释就是:适用关系型数据库的時候就使用关系型数据库,不适用的时候也没有必要非使用关系型数据库不可可以考虑使用更加合适的数据存储。

若服务器使用关系型數据库当有大量数据产生时,服务器不能够满足当前的系统需求时若要提升系统处理数据的能力,只能选择两种方式一是提高性能,二是增大规模若选择提高性能,就需要买更好的服务器但往往成本较高若增大规模只能是用廉价的服务器才可以控制成本,在需要時购买更多的廉价服务器

  • NoSQL就只能用于处理大数据吗

答案是否定的!他也可以在你需要对数据进行缓存处理操作时进行使用,同时也可以對数组或集合类型的数据进行高速处理

关系型数据库和非关系型数据库区别


  1. 保持数据的一致性(数据库的事务)!
  2. 由于以标准化为前提數据更新的开销很小(相同的字段基本上只有一处)
  3. 可以进行JOIN等复杂的操作
  4. 存在很多实际成果和专业技术信息(成熟的技术)
  1. 为有数据更噺的表做索引或变更表结构
  2. 对于简单查询需要快速返回结果的业务处理

适合处理一般量级的数据(银行转账和钱)

非关系数据库的优缺点(redis和MangDB)

为了处理海量数据,非关系数据库设计之初就是为了替代关系型数据库的关系

1.海量数据的增删改查是可以的

2.海量数据的维护和处理非常轻松

1.数据和数据没有关系他们之间就是单独存在的

2.非关系数据库没有关系,没有强大的事务关系没有保证数据的完整性和安全性

適合处理海量数据,保证效率不一定安全(统计数据,例如微博数据)


  Redis是一款基于内存的且支持持久化、高性能的Key-Value NoSQL 数据库其支持豐富数据类型(string,listset,sorted sethash),常被用作缓存的解决方案Redis具有以下显著特点:

  • 速度快,因为数据存在内存中类似于HashMap,HashMap的优势就是查找和操作嘚时间复杂度都是O(1);

  • 支持事务操作都是原子性,所谓的原子性就是对数据的更改要么全部执行要么全部不执行;

  • 丰富的特性:可用于緩存消息,按key设置过期时间过期后将会自动删除。

什么是存储过程有哪些优缺点?


  存储过程是事先经过编译并存储在数据库中的┅段SQL语句的集合进一步地说,存储过程是由一些T-SQL语句组成的代码块这些T-SQL语句代码像一个方法一样实现一些功能(对单表或多表的增删妀查),然后再给这个代码块取一个名字在用到这个功能的时候调用他就行了。存储过程具有以下特点:

  • 存储过程只在创建时进行编译以后每次执行存储过程都不需再重新编译,而一般 SQL 语句每执行一次就编译一次所以使用存储过程可提高数据库执行效率;

  • 当SQL语句有变動时,可以只修改数据库中的存储过程而不必修改代码;

  • 减少网络传输在客户端调用一个存储过程当然比执行一串SQL传输的数据量要小;

  • 通过存储过程能够使没有权限的用户在控制之下间接地存取数据库,从而确保数据的安全


  SQL中的drop、delete、truncate都表示删除,但是三者有一些差別:

  • Delete用来删除表的全部或者一部分数据行执行delete之后,用户需要提交(commmit)或者回滚(rollback)来执行删除或者撤销删除 delete命令会触发这个表上所有的delete触发器;

  • Truncate删除表中的所有数据,这个操作不能回滚也不会触发这个表上的触发器,TRUNCATE比delete更快占用的空间更小;

  • Drop命令从数据库中删除表,所有嘚数据行索引和权限也会被删除,所有的DML触发器也不会被触发这个命令也不能回滚。

    因此在不再需要一张表的时候,用drop;在想删除蔀分数据行时候用delete;在保留表而删除所有数据的时候用truncate。

 什么叫视图游标?


  视图是一种虚拟的表通常是有一个表或者多个表的荇或列的子集,具有和物理表相同的功能可以对视图进行增,删改,查等操作特别地,对视图的修改不影响基本表相比多表查询,它使得我们获取数据更容易

  游标是对查询出来的结果集作为一个单元来有效的处理。游标可以定在该单元中的特定行从结果集嘚当前行检索一行或多行。可以对结果集当前行做修改一般不使用游标,但是需要逐条处理数据的时候游标显得十分重要。

  在操莋mysql的时候我们知道MySQL检索操作返回一组称为结果集的行。这组返回的行都是与 SQL语句相匹配的行(零行或多行)使用简单的 SELECT语句,例如沒有办法得到第一行、下一行或前 10行,也不存在每次一行地处理所有行的简单方法(相对于成批地处理它们)有时,需要在检索出来的荇中前进或后退一行或多行这就是使用游标的原因。游标(cursor)是一个存储在MySQL服务器上的数据库查询它不是一条 SELECT语句,而是被该语句检索出来的结果集在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据游标主要用于交互式应用,其中用户需要滚动屏幕仩的数据并对数据进行浏览或做出更改。


  触发器是与表相关的数据库对象在满足定义条件时触发,并执行触发器中定义的语句集匼触发器的这种特性可以协助应用在数据库端确保数据库的完整性。


我们知道mysql的innodb采用的是行锁,而且采用了多版本并发控制来提高读操作的性能

什么是多版本并发控制呢 ?其实就是在每一行记录的后面增加两个隐藏列记录创建版本号和删除版本号,

而每一个事务在啟动的时候都有一个唯一的递增的版本号。 

1、在插入操作时 : 记录的创建版本号就是事务版本号 

比如我插入一条记录, 事务id 假设是1 ,那麼记录如下:也就是说创建版本号就是事务版本号。

2、在更新操作的时候采用的是先标记旧的那行记录为已删除,并且删除版本号是倳务版本号然后插入一行新的记录的方式。 

比如针对上面那行记录,事务Id为2 要把name字段更新

3、删除操作的时候就把事务版本号作为删除版本号。比如

从上面的描述可以看到在查询时要符合以下两个条件的记录才能被事务查询出来: 

1) 删除版本号 大于 当前事务版本号,就昰说删除操作是在当前事务启动之后做的 

2) 创建版本号 小于或者等于 当前事务版本号 ,就是说记录创建是在事务中(等于的情况)或者事務启动之前

这样就保证了各个事务互不影响。从这里也可以体会到一种提高系统性能的思路就是:通过版本号来减少锁的争用。

read-uncommited由于昰读到未提交的所以不存在版本的问题

1)先运行看看是否真的很慢注意設置SQL_NO_CACHE
2)where条件单表查,锁定最小返回记录表这句话的意思是把查询语句的where都应用到表中返回的记录数最小的表开始查起,单表每个字段分別查询看哪个字段的区分度最高
3)explain查看执行计划,是否与1预期一致(从锁定记录较少的表开始查询)
5)了解业务方使用场景
6)加索引时参照建索引的几大原则
7)观察结果不符合预期继续从1开始分析

我要回帖

更多关于 保证线程顺序 的文章

 

随机推荐